I switched my Boost version from 1.6.1 to >=1.6.2 and my boost::spirit
parser code fails to compile. Actually, I thinking the problem has something to do with a bug fix in Boost Variant from version 1.6.1 to version 1.6.2.
Release notes of version 1.6.2 say:
Variant constructors and assignment operators now do not participate in overload resolutions if variant can not hold the input type #5871, #11602
Here is a stripped version of my failing code:
Parser.h
#pragma once
#include <string>
#include <boost/variant.hpp>
struct AccTag {};
template <typename tag> struct unop;
typedef unop<AccTag> Acc;
typedef boost::variant<
boost::recursive_wrapper<Acc>
> computationExpr;
typedef boost::variant<
boost::recursive_wrapper<computationExpr>,
int
> expr;
template <typename tag> struct unop
{
unop() : oper1() {
}
explicit unop(const expr& o) : oper1(o) { }
expr oper1;
};
expr parse(const std::string& expression, bool& ok);
Parser.cpp
#include "Parser.h"
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
using namespace boost;
template <typename Iterator = std::string::iterator, typename Skipper = spirit::qi::space_type>
class ParserImpl : public spirit::qi::grammar<Iterator, expr(), Skipper>
{
public:
ParserImpl() : ParserImpl::base_type(expr_)
{
using namespace boost::spirit::qi;
using namespace boost::phoenix;
expr_ = props_.alias();
props_ = (
(lit("Acc") >> "(" >> int_ >> ")")[_val = construct<Acc>(_1) /* Most likely the source of the error */]
);
}
spirit::qi::rule<Iterator, expr(), Skipper> props_;
spirit::qi::rule<Iterator, expr(), Skipper> expr_;
};
expr parse(const std::string& expression, bool& ok)
{
expr result;
std::string formula = expression;
ParserImpl<> parser;
auto b = formula.begin();
auto e = formula.end();
ok = spirit::qi::phrase_parse(b, e, parser, spirit::qi::space, result);
if (b != e) {
ok = false;
}
return result;
}
The code compiles without problems in Version 1.6.1, but fails in Version 1.6.2 with the error:
.../proto/transform/default.hpp(154): error C2679: Binary operator "=": ...
I guess in Version 1.6.1 there was an implicit conversion from computationExpr
to expr
, which is no longer allowed.
How can I fix this code? I think something in _val = construct<Acc>(_1)
must be changed, but I'm lacking the skills to do it.