boost::any 列表上的多态运算符

发布于 2024-10-02 22:20:19 字数 420 浏览 8 评论 0原文

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

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

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

(我确实有这样做的充分理由......我正在实现一个解释器)

Suppose I have a list of type list<boost::any> that has some type in it that is unknown. Now suppose I want to apply some operation to the elements in the list that is polymorphic. In this case, consider the + operator. Suppose that I know that the list will always contain a homogenous set of objects that support operator+, and I want to get the result of applying operator+ (the "sum" in one sense) between each element of the list into a new boost::any. Something like this:

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

Without enumerating all possible types that could support operator+, is there a way to do this? I'm extremely open to crazy ideas.

(I really do have an ok reason for doing this... I'm implementing an interpreter)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

柠檬色的秋千 2024-10-09 22:20:19

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

我不明白如何在没有 operator+ 函数网格来处理所包含类型或常规运行时多态性的每种可能组合的情况下做到这一点。

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

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

You could use boost::variant instead if you know the range of possible types in the list.

I don't see how you can do this without a mesh of operator+ functions to handle every possible combination of contained types, or regular runtime polymorphism.

What is the concrete type you wish to see in the final boost::any output, I wonder?

btw if you are implementing an interpreter, check out Boost.Spirit which might illuminate your design problem here.

合约呢 2024-10-09 22:20:19

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

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

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

C++ matches functions (and operators are merely fancy functions that have an additional infix syntax) by their types, not by their names, at compile-time. (Rather than checking at run-time whether the objects involved support the requested operation.)
The only exception to that I can think of is virtual functions. If the types were polymorphic, you could use any of the workarounds for missing multi-methods (double dispatch). But since they can be anything, I don't think you can do this.

If you have a limited set of types, template-meta programming might help the generate functions implementing addition. But if the number of types involved were limited, you'd probably use boost::variant.

(IME saying this means that, in very short time, someone comes along and proves me wrong.)

尹雨沫 2024-10-09 22:20:19

不。 不适用于 boost::any 或 boost::variant (不符合您的“不枚举可以支持运算符+的所有可能类型”的要求)。

你需要做的是自己做。 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+会对泛型类型做什么,所以我编了一些对我来说有点意义的东西。您当然需要根据您的需求进行更改。

No. Not with boost::any nor with boost::variant (doesn't qualify your, "Without enumerating all possible types that could support operator+," requirement).

What you need to do is make your own. The concept behind boost::any is quite simple. If you look at the documentation they have a link to an article explaining the technique (it's basically the handle/body idiom with polymorphism). All you need to do is decide what interface your various objects must have and write the 'any' interface and it's impl accordingly. Something resembling something like so:

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();
}

It's hard to imagine what operator+ would do on generic types so I made something up that makes a small amount of sense to me. You'll of course need to change to your needs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文