提升精神语义动作要求

时间:2013-05-17 15:17:28

标签: c++ boost boost-spirit

考虑以下行动

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提示了类似的内容。

这里需要constness吗? http://www.boost.org/doc/libs/1_53_0/libs/spirit/doc/html/spirit/qi/reference/action.html中的文档仅表示需要签名void( Attrib&, Context, bool& )

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

  

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

在这种情况下。

1 个答案:

答案 0 :(得分:3)

  

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
}

  

问题1:此处是否需要常量? http://www.boost.org/doc/libs/1_53_0/libs/spirit/doc/html/spirit/qi/reference/action.html中的文档仅说明签名无效(Attrib&amp;,Context,bool&amp;)。

A。该库可能不是明确,但是C ++语言要求隐含地 <由于您使用解析器表达式的方式 1

表达式模板

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

产生一个临时,当传递给qi::parse API时,只能绑定到 const 引用 2,3 。这就是&#39; const&#39;在整个解析器中引入了表达式,并且它同样扩展到子表达式的成员,例如存储语义动作d的子表达式。

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


1。经过深思熟虑,它并不真正取决于你如何使用它。我的解释逻辑是合理的,但由于精神甚至支持内联解析器表达式,call() - 解析器必然一个const成员操作该解析器,因此所有其他操作无论如何都将在const上下文中。事实上,在boost::spirit::traits::action_dispatch::operator()中,您会看到以F const&传递的可调用对象,例如反映这一点。

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

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