【问题标题】:How to return heap allocated values in Boost Spirit Qi如何在 Boost Spirit Qi 中返回堆分配的值
【发布时间】:2014-04-21 19:44:21
【问题描述】:

因为我有这样的课程:

 class Test {
   void setVersion(Version *version);
   Version* version() const;
   private:
      Version *m_version;
 };

我使用 BOOST_FUSION_ADAPT_ADT 进行了调整 我发现的一种方法是使用

 [_val = phoenix::new_<Version>(Version(0))]

在语义操作中,但这对我来说似乎是一个肮脏的解决方法。 请注意,通常我不会使用堆分配的对象,但在这种情况下,带有指针的 API 已经以这种方式修复了。

【问题讨论】:

    标签: c++ boost boost-spirit


    【解决方案1】:

    这里有很多下意识的反射:

    1. 确实,这里不要使用指针
    2. Rule Of Zero

    我的意思是,重新考虑您的问题。是的,我可以想出一些方法来解决回溯泄漏的问题,但它们都很丑陋、容易出错,而且最重要的是可能不需要。

    让我们考虑一下。

    1. 为什么Version 会被非拥有指针引用?

      嗯,最合理的解释是该版本可能具有较大的附加数据和其他内容(序列化策略、日志记录、验证内容等。Version 可以添加任何可以想象到的运行时多态行为)。

      此信息对于“属于”某个版本的任何对象都是“外部”的,因此此版本“元信息”不会被多态地拥有和引用是有道理的。

    2. 这是什么意思?

      在我看来,这可能意味着解析期间可能出现的任何版本都必须在解析开始时就已经知道。在这种情况下,不需要在解析过程中动态构造(很多很多,可能是重复的)版本的实例根本

    3. 是的,但如果不是呢?

      假设您一开始没有这个“版本表”。很可能,您不希望 AST 中的每个节点都以它们自己唯一的 Version 实例结束,即使它引用相同的版本。因此,您可能应该制作一个工厂函数,

      • 维护(唯一)版本的“共享”表
      • 能够在解析过程中查找版本项(因此您可以在解析的节点中设置Version*
      • 可选地实例化一个新的 Version 对象,当且仅当它在查找时尚不存在

      现在这个表可以是所有 Version 实例的所有者,并且可以在您使用完它们后立即将它们全部释放。

    【讨论】:

    • 现在,如果我使用共享指针,除了泄漏点之外,我可能会遇到同样的问题。我的问题更多是关于如何从仍然使用 %= 运算符和带有 getter 和 setter 的版本调整结构的规则返回堆分配的结构/共享指针。如果可能,我不想使用凤凰语义动作。
    • 你怎么能不呢? rule&lt;It, T*()&gt; myrule = qi::eps [ qi::val = phx::new_&lt;T&gt;() ]; 正是这样做的。另请注意,我确实建议您使用共享指针(原因很简单,您说您不能更改类)。
    • @Baradé 如果您感兴趣,我刚刚创建了一种使用堆分配值的方法 - 安全 - here。也许你可以使用它,如果只是为了想法?
    • 这很有趣,尽管使用 boost::recursive_wrapper 这样的标准解决方案/模式会更好。有没有办法在不编写自定义类型“CommandHolder”并使用标准类型的情况下做到这一点?仅用于简化代码
    • 如果你想简化代码,使用值语义。这是图书馆的设计。如果您不想,只需滚动您自己的解析器。这是一种权衡。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多