【问题标题】:boost spirit semantic action requirements提升精神语义动作要求
【发布时间】:2013-05-17 15:17:27
【问题描述】:

鉴于以下操作

struct Data {
    double d;
    void operator()( double dd,
                     boost::spirit::qi::unused_type,
                     boost::spirit::qi::unused_type )
    { d = dd; }
};

struct Printer {
    void operator()( double dd,
                     boost::spirit::qi::unused_type,
                     boost::spirit::qi::unused_type ) const
    { std::cout << dd; }
};

代码

void foo( const std::string &s ) {
    Printer p;
    boost::spirit::qi::parse( s.begin(), s.end(),
                              boost::spirit::qi::double_[ p ] );
}

编译时

double foo( const std::string &s ) {
    Data d;
    boost::spirit::qi::parse( s.begin(), s.end(),
                              boost::spirit::qi::double_[ d ] );
    return d.d;
}

没有。

查看http://www.boost.org/doc/libs/1_53_0/libs/spirit/doc/html/spirit/qi/tutorials/semantic_actions.html 中的示例,可以看到函数对象使用operator() 声明的const。 MSVC 的错误消息 C3848 暗示了类似的内容。

这里需要常量吗? http://www.boost.org/doc/libs/1_53_0/libs/spirit/doc/html/spirit/qi/reference/action.html 中的文档只说签名void( Attrib&amp;, Context, bool&amp; ) 是必需的。

备注:我必须承认我不是很理解这句话

函数或函数对象应将值返回给 通过将其分配给第一个参数 attr 来生成输出。

在这种情况下。

【问题讨论】:

    标签: c++ boost boost-spirit


    【解决方案1】:

    Q.2:备注:我必须承认我不是很理解这句话

    A. 您可以查看boost spirit semantic action parameters 以获得更深入的解释。这是简短的版本:

    void action_f(std::string& attribute, 
            qi::unused_type const& context, 
            bool& flag)
    {
        boost::fusion::at_c<0>(context.attributes) = "hello world"; // return the attribute value
        flag = true; // signal parse success
    }
    

    Q.1:这里需要常量吗? http://www.boost.org/doc/libs/1_53_0/libs/spirit/doc/html/spirit/qi/reference/action.html 中的文档只说需要签名 void( Attrib&, Context, bool& )。

    A. const-ness 可能不是库明确要求的,但是要求是隐含 C++ 语言引入的由于您使用解析器表达式的方式1:

    表达式模板

    boost::spirit::qi::double_[ d ]
    

    产生一个 临时的,当传递给 qi::parse API 时只能绑定到 const 参考2,3 .这是在整个解析器表达式中引入“const”的地方,它同样扩展到子表达式的成员,例如那些存储语义动作的成员,d

    因此,在延迟调用时d 的实例在逻辑上将是const,因此不会选择operator(),而operator() const 会。


    1. 仔细想想,这并不取决于你如何使用它。我的解释的逻辑是合理的,但是因为 Spirit 甚至 支持 内联解析器表达式,call()-ing 解析器必然是该解析器上的 const 成员操作,并且因此,所有其他操作无论如何都将在const 上下文中。事实上,在boost::spirit::traits::action_dispatch::operator() 中,您会看到可调用对象作为F const&amp; 传递,例如反映这一点。

    2. Spirit V2 不支持规则的移动语义 - 事实上,它也不需要它们

    3. 根据标准,临时的生命周期将延长到包含完整表达式的末尾

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      • 2019-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-06
      • 1970-01-01
      相关资源
      最近更新 更多