我的一条规则看起来像这样
set_name
= ( tok.set_ >> tok.name_ >> tok.identifier )
[
std::cout << val("set name statement to: ") << _3 << "\n"
]
;
这很有效。出现时
SET NAME xyz
按预期输出
将name statement设置为:xyz
现在我想做一些有用的事情,将找到的名字存储在一个类中。在parser semantic examples工作我写了这段代码
class writer
{
public:
void print(string const& s) const
{
std::cout << s << std::endl;
}
};
writer w;
...
set_name
= ( tok.set_ >> tok.name_ >> tok.identifier )
[
boost::bind( &writer::print, &w, ::_3 )
]
;
这不编译
1>C:\Program Files\boost\boost_1_44\boost/bind/bind.hpp(318) : error C2664: 'R boost::_mfi::cmf1::operator ()(const U &,A1) const' : cannot convert parameter 2 from 'bool' to 'const std::basic_string ' 1> with 1> [ 1> R=void, 1> T=eCrew::rule::writer, 1> A1=const std::string &, 1> U=eCrew::rule::writer * 1> ] 1> and 1> [ 1> _Elem=char, 1> _Traits=std::char_traits, 1> _Ax=std::allocator 1> ] 1> Reason: cannot convert from 'bool' to 'const std::string' 1> No constructor could take the source type, or constructor overload resolution was ambiguous
为什么编译器抱怨尝试从bool转换为字符串?我看不到布尔。
答案 0 :(得分:3)
中的占位符
std::cout << val("set name statement to: ") << _3 << "\n"
指的是boost::spirit::_3
,它是一个boost.phoenix v2占位符。
boost::bind(&writer::print, &w, ::_3)
是一个boost.bind占位符(当然)。
这些占位符不共享相同的行为,甚至引用相同的数据。形式为_ N 的Phoenix占位符引用解析器的第N个子属性,而绑定占位符具有不同的含义:
bool&
'点'参数在您的情况下,最简单的解决方案是使用boost::phoenix::bind
而不是boost::bind
,以便您可以继续使用_3
来引用解析器的第三个子属性,而不必选择它在writer::print
内手动输出。
或者,只将语义操作附加到tok.identifier
,以便boost.bind的::_1
按预期工作:
set_name
= tok.set_
>> tok.name_
>> tok.identifier[boost::bind(&writer::print, &w, ::_1)]
;