使用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)
,我得到了失败的模板实例化。上下文并不重要,因为我以另一种方式在我的真实代码库中解决了这个问题,但我想知道为什么这不起作用。
答案 0 :(得分:1)
在我的编译器/增强版本上它可以工作另请参阅 Live On Coliru
一时兴起,我怀疑那些已经悄悄进入“旧”Phoenix V2实施的漏洞。菲尼克斯V2在技术上仍然是精神图书馆的一部分。它已被Phoenix V3取代,它作为boost/phoenx/...
中的独立库。
Boost Phoenix V2显示出时代的裂缝 - 主要是在BOOST_RESULT_OF()实用程序使用decltype
的现代编译器上。
长话短说
尝试使用
#define BOOST_SPIRIT_USE_PHOENIX_V3
如果您的编译器/升级组合没有选择它,请使用它.¹
相反,如果您的编译器是旧的,请尝试
#define BOOST_RESULT_OF_USE_TR1
¹最近的Spirit版本放弃了Phoenix V2: Farewell Phoenix-v2