1

鉴于以下动作

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&, Context, bool& )

备注:我必须承认我不太明白这句话

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

在这种情况下。

4

1 回答 1

3

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

A.你可以看一下boost Spirit语义动作参数来进行深入的解释。这是简短的版本:

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,但是由于您使用解析器表达式1的方式,C++ 语言隐含地引入了该要求:

表达式模板

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

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

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


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

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

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

于 2013-05-17T19:16:05.403 回答