精神解析器不适合与auto
一起使用吗?
一个简单的解析器在传递到内联qi::parse()
时工作正常,但如果通过auto
变量传递,则会因段错误而崩溃:
#include <cstdio>
#include <string>
#include <boost/spirit/include/qi.hpp>
using namespace std;
namespace qi = boost::spirit::qi;
int main()
{
string line = "[z]";
auto bracketed_z = '[' >> +qi::char_('z') >> ']';
auto p = line.cbegin();
printf("%d", qi::parse(p, line.cend(), '[' >> +qi::char_('z') >> ']')); // Works
p = line.cbegin();
printf("%d", qi::parse(p, line.cend(), bracketed_z)); // Crashes
}
使用 g++-4.8 和 VC13 进行重现。
更新:修复了原始代码中的一个错误(p
在第二次调用 parse()
之前没有重新初始化)。
Parsers 不是为在 Spirit V2 中与auto
一起使用而设计的。
这是因为基础 Proto 表达式模板包含对临时项的引用。
您可以使用
-
qi::copy()
(boost_1_55_0后存在于主干中,目前不在任何已发布版本中) -
boost::proto::deep_copy
- 或BOOST_SPIRIT_AUTO(首先在这里创造)
我经常在SO上写过这些事情:https://stackoverflow.com/search?q=user%3A85371+deep_copy,特别是这个:
- 提升精神 V2 气与优化级别相关的错误
Boost Spirit X3 將沒有此限制。
Boost.Spirit 使用表达式模板,不适用于auto
。解决方法是使用boost::proto::deep_copy
:
auto bracketed_z = proto::deep_copy('[' >> +qi::char_('z') >> ']');