2

假设我有一个类型列表,list<boost::any>其中包含某种未知类型。现在假设我想对列表中的多态元素应用一些操作。在这种情况下,请考虑 + 运算符。假设我知道列表将始终包含一组支持 operator+ 的同质对象,并且我想获得在列表的每个元素之间应用 operator+(某种意义上的“总和”)的结果到一个新的 boost::任何。像这样的东西:

boost::any sum(list<boost::any> lst) {
    // return lst[0]+lst[1]+lst[2] etc
}

如果不枚举所有可能支持 operator+ 的可能类型,有没有办法做到这一点?我对疯狂的想法非常开放。

(我确实有这样做的正当理由......我正在实施解释器)

4

3 回答 3

3

boost::variant如果您知道列表中可能类型的范围,则可以改用。

operator+如果没有函数网格来处理包含类型的每种可能组合或常规运行时多态性, 我看不出你怎么能做到这一点。

我想知道您希望在最终boost::any输出中看到的具体类型是什么?

顺便说一句,如果您正在实现解释器,请查看Boost.Spirit,它可能会在此处阐明您的设计问题。

于 2010-11-12T18:35:41.920 回答
1

C++在编译时通过类型而不是名称来匹配函数(并且运算符只是具有附加中缀语法的花哨的函数)。(而不是在运行时检查所涉及的对象是否支持请求的操作。)
我能想到的唯一例外是虚函数。如果类型是多态的,您可以使用任何解决方法来缺少多方法(双重分派)。但既然它们可以是任何东西,我认为你不能这样做

如果您的类型有限,模板元编程可能有助于生成实现加法的函数。但如果涉及的类型数量有限,您可能会使用boost::variant.

(IME 说这意味着,在很短的时间内,有人出现并证明我错了。)

于 2010-11-12T18:35:54.770 回答
1

不。不使用 boost::any 也不使用 boost::variant (不符合您的“不枚举所有可能支持 operator+ 的可能类型”的要求)。

你需要做的是自己做。boost::any 背后的概念非常简单。如果您查看文档,他们有一个链接到解释该技术的文章(它基本上是具有多态性的句柄/主体习语)。您需要做的就是确定各种对象必须具有的接口并编写“任何”接口并相应地实现。类似于这样的东西:

struct my_any
{
  template < typename T >
  my_any(T const& t) : pimpl(new impl<T>(t)) {}
  ...
  some_type get_some_type() const;
   ...
private:
  struct impl_base
  {
    ....
    virtual some_type get_some_type() const = 0;
  };
  template < typename T >
  struct impl : impl_base
  {
    some_type get_some_type() const { return t.get_some_type(); }
    impl(T const& t_var) : t(t_var) {}
    ....
  };
  boost::scoped_ptr<impl_base> pimpl;
};

some_type operator+ (my_any const& a, my_any const& b)
{
  return a.get_some_type() + b.get_some_type();
}

很难想象 operator+ 会对泛型类型做什么,所以我编造了一些对我来说意义不大的东西。你当然需要改变你的需求。

于 2010-11-12T19:10:51.903 回答