考虑以下行动
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
来生成输出。
在这种情况下。
答案 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. 根据标准,临时的生命周期将延伸到包含完整表达式的末尾