为什么我似乎不能使用 qi locals 作为 eps 的语义谓词?

Why can't I seem to use qi locals as the semantic predicate to eps?

当使用 qi::locals 时,局部参数似乎不能用作 eps 的语义谓词。这是一个精简的虚构示例:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
using namespace qi::labels;
using qi::eps;

template <typename Iterator, typename Any>
struct parser : qi::grammar<Iterator, Any(), qi::locals<bool> > {
    parser() : parser::base_type(p) {
        p = eps[_a=false] >> eps(_a);
    }
    qi::rule<Iterator, Any(), qi::locals<bool> > p;
};

int main(int argc, const char *argv[]) {
    int val;
    std::string data;
    auto i = data.cbegin();
    auto end = data.cend();
    parser<decltype(i), decltype(val) > p;
    bool rv = phrase_parse(i, end, p, ascii::blank, val);
    return rv ? 0 : 1;
}

在这个例子中,如果我在第二个 eps 之后删除 (_a),一切都会干净地编译。使用 (_a),我得到了一大堆失败的模板实例化。上下文无关紧要,因为我已经在我的真实代码库中以另一种方式解决了这个问题,但我想知道为什么这不起作用。

在我的 compilers/boost 版本上有效 另见 Live On Coliru

一时兴起,我怀疑 "old" Phoenix V2 实施中存在错误。凤凰V2在技术上仍然是武魂图书馆的一部分。它已被 Phoenix V3 取代,Phoenix V3 在 boost/phoenx/....

中作为单独的库存在

Boost Phoenix V2 显示出时代的裂缝 - 主要是在 BOOST_RESULT_OF() 实用程序使用 decltype.

的现代编译器上

长话短说

  1. 尝试使用

     #define BOOST_SPIRIT_USE_PHOENIX_V3
    

    如果您的 compiler/boost 组合不 select 则使用它。¹

  2. 反之,如果你的编译器比较旧,试试

    #define BOOST_RESULT_OF_USE_TR1
    

¹ 最近的 Spirit 版本掉落了 Phoenix V2:Farewell Phoenix-v2