将解析器分配给自动变量



精神解析器不适合与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() 之前没有重新初始化)。

Spirit

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') >> ']');

最新更新