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

时间:2015-04-10 02:00:23

标签: boost-spirit-qi boost-phoenix

使用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;
}

在此示例中,如果我在第二个(_a)之后删除eps,则所有内容都会干净地编译。使用(_a),我得到了失败的模板实例化。上下文并不重要,因为我以另一种方式在我的真实代码库中解决了这个问题,但我想知道为什么这不起作用。

1 个答案:

答案 0 :(得分:1)

在我的编译器/增强版本上它可以工作另请参阅 Live On Coliru

一时兴起,我怀疑那些已经悄悄进入“旧”Phoenix V2实施的漏洞。菲尼克斯V2在技术上仍然是精神图书馆的一部分。它已被Phoenix V3取代,它作为boost/phoenx/...中的独立库。

Boost Phoenix V2显示出时代的裂缝 - 主要是在BOOST_RESULT_OF()实用程序使用decltype的现代编译器上。

长话短说

  1. 尝试使用

     #define BOOST_SPIRIT_USE_PHOENIX_V3
    

    如果您的编译器/升级组合没有选择它,请使用它.¹

  2. 相反,如果您的编译器是旧的,请尝试

    #define BOOST_RESULT_OF_USE_TR1
    

  3. ¹最近的Spirit版本放弃了Phoenix V2: Farewell Phoenix-v2