I have a C++ code that uses boost 1.60 and compiles fine. It is a simple math parser.
Code is here with CI that shows that it compiles fine with gcc
Updating to boost 1.79 leads to the following compilation error error: no matching function for call to 'boost::variant'
I have isolated the problem with this code, and spotted the constructor that creates the error (with comments)
Any advise would be helpful!
#include <cstdint>
#include <iostream>
#include <boost/variant.hpp>
#include <boost/version.hpp>
#include <boost/foreach.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/qi.hpp>
#define INCLUDE_FROM_BOOST_1_79
#ifdef INCLUDE_FROM_BOOST_1_79
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/fusion.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/phoenix/object.hpp>
#include <boost/phoenix/stl.hpp>
#else
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#endif
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
using qi::double_;
using qi::eol;
using qi::lit;
using qi::lexeme;
using qi::on_error;
using qi::fail;
using ascii::char_;
using ascii::alpha;
using ascii::alnum;
using ascii::string;
using namespace qi::labels;
using phoenix::at_c;
using phoenix::push_back;
using phoenix::construct;
using phoenix::val;
namespace maneuvering
{
typedef ascii::blank_type SpaceType;
struct Nil
{
};
struct FunctionCall;
typedef std::string Identifier;
typedef boost::variant<
Nil
, double
, Identifier
, boost::recursive_wrapper<FunctionCall>
>
Atom;
struct Expr;
typedef boost::variant<
Nil
, boost::recursive_wrapper<Expr>
, boost::recursive_wrapper<Atom>
>
Base;
struct Factor
{
Base base;
std::vector<Base> exponents;
};
struct OperatorAndFactor
{
std::string operator_;
Factor factor;
};
struct Term
{
Factor first;
std::vector<OperatorAndFactor> rest;
};
struct OperatorAndTerm
{
std::string operator_;
Term term;
};
struct Expr
{
Term first;
std::vector<OperatorAndTerm> rest;
};
struct FunctionCall
{
Identifier function;
Expr expr;
};
}
BOOST_FUSION_ADAPT_STRUCT(
maneuvering::Factor,
(maneuvering::Base, base)
(std::vector<maneuvering::Base>, exponents)
)
BOOST_FUSION_ADAPT_STRUCT(
maneuvering::OperatorAndTerm,
(std::string, operator_)
(maneuvering::Term, term)
)
BOOST_FUSION_ADAPT_STRUCT(
maneuvering::OperatorAndFactor,
(std::string, operator_)
(maneuvering::Factor, factor)
)
BOOST_FUSION_ADAPT_STRUCT(
maneuvering::Term,
(maneuvering::Factor, first)
(std::vector<maneuvering::OperatorAndFactor>, rest)
)
BOOST_FUSION_ADAPT_STRUCT(
maneuvering::Expr,
(maneuvering::Term, first)
(std::vector<maneuvering::OperatorAndTerm>, rest)
)
BOOST_FUSION_ADAPT_STRUCT(
maneuvering::FunctionCall,
(maneuvering::Identifier, function)
(maneuvering::Expr, expr)
)
namespace maneuvering
{
struct ArithmeticGrammar : qi::grammar<std::string::const_iterator, Expr(), SpaceType>
{
// Begin of the section that create boost compilation problem
ArithmeticGrammar() : ArithmeticGrammar::base_type(expr)
{
using boost::spirit::ascii::alnum;
using boost::spirit::ascii::alpha;
expr = term >> *(operator_and_term);
add_operators = qi::char_("+") | qi::char_("-");
mul_operators = qi::char_("*") | qi::char_("/");
operator_and_term = add_operators >> term;
operator_and_factor = mul_operators >> factor;
term = factor >> *(operator_and_factor);
factor = base >> *( '^' >> exponent);
base = ('(' >> expr >> ')') | atom; // Specific problematic line
exponent = base;
atom = function_call | identifier | double_;
function_call = identifier >> '(' >> expr >> ')';
identifier = alpha >> *(alnum | qi::char_('_'));
}
// End of the section that create boost compilation problem
qi::rule<std::string::const_iterator, Expr(), SpaceType> expr;
qi::rule<std::string::const_iterator, std::string(), SpaceType> add_operators;
qi::rule<std::string::const_iterator, std::string(), SpaceType> mul_operators;
qi::rule<std::string::const_iterator, OperatorAndTerm(), SpaceType> operator_and_term;
qi::rule<std::string::const_iterator, OperatorAndFactor(), SpaceType> operator_and_factor;
qi::rule<std::string::const_iterator, Term(), SpaceType> term;
qi::rule<std::string::const_iterator, Factor(), SpaceType> factor;
qi::rule<std::string::const_iterator, Base(), SpaceType> base;
qi::rule<std::string::const_iterator, Base(), SpaceType> exponent;
qi::rule<std::string::const_iterator, Atom(), SpaceType> atom;
qi::rule<std::string::const_iterator, FunctionCall(), SpaceType> function_call;
qi::rule<std::string::const_iterator, Identifier(), SpaceType> identifier;
};
}
int main(int argc, char* agrv[])
{
std::cout << "Using Boost "
<< BOOST_VERSION / 100000 << "." // major version
<< BOOST_VERSION / 100 % 1000 << "." // minor version
<< BOOST_VERSION % 100 // patch level
<< std::endl;
}
Error is below
In file included from /usr/local/include/boost/spirit/home/qi/auxiliary/attr.hpp:18,
from /usr/local/include/boost/spirit/home/qi/auxiliary.hpp:19,
from /usr/local/include/boost/spirit/home/qi.hpp:16,
from /usr/local/include/boost/spirit/include/qi.hpp:16,
from main.cpp:8:
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp: In instantiation of 'static void boost::spirit::traits::assign_to_attribute_from_value<Attribute, T, Enable>::call(const T_&, Attribute&, mpl_::false_) [with T_ = boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >; Attribute = boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >; T = boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >; Enable = void; mpl_::false_ = mpl_::bool_<false>]':
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:171:17: required from 'static void boost::spirit::traits::assign_to_attribute_from_value<Attribute, T, Enable>::call(const T&, Attribute&) [with Attribute = boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >; T = boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >; Enable = void]'
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:370:63: required from 'void boost::spirit::traits::detail::assign_to(const T&, Attribute&, mpl_::false_) [with T = boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >; Attribute = boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >; mpl_::false_ = mpl_::bool_<false>]'
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:393:26: required from 'void boost::spirit::traits::assign_to(const T&, Attribute&) [with T = boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >; Attribute = boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >]'
/usr/local/include/boost/spirit/home/qi/detail/alternative_function.hpp:109:34: required from 'bool boost::spirit::qi::detail::alternative_function<Iterator, Context, Skipper, Attribute>::call_variant(const Component&, mpl_::false_) const [with Component = boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0> > >; Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; Context = boost::spirit::context<boost::fusion::cons<boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >&, boost::fusion::nil_>, boost::fusion::vector<> >; Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >; Attribute = boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >; mpl_::false_ = mpl_::bool_<false>]'
/usr/local/include/boost/spirit/home/qi/detail/alternative_function.hpp:132:32: required from 'bool boost::spirit::qi::detail::alternative_function<Iterator, Context, Skipper, Attribute>::call_optional_or_variant(const Component&, mpl_::false_) const [with Component = boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0> > >; Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; Context = boost::spirit::context<boost::fusion::cons<boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >&, boost::fusion::nil_>, boost::fusion::vector<> >; Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >; Attribute = boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >; mpl_::false_ = mpl_::bool_<false>]'
/usr/local/include/boost/spirit/home/qi/detail/alternative_function.hpp:139:44: [ skipping 12 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/boost/function/function_template.hpp:720:22: required from 'boost::function4<R, T1, T2, T3, T4>::function4(Functor, typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, false>, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, maneuvering::Expr(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type> >, boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, false>, boost::fusion::nil_> > > >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0> > >, boost::fusion::nil_> > >, mpl_::bool_<false> >; R = bool; T0 = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >&; typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type = int]'
/usr/local/include/boost/function/function_template.hpp:1094:16: required from 'boost::function<R(T0, T1, T2, T3)>::function(Functor, typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, false>, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, maneuvering::Expr(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type> >, boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, false>, boost::fusion::nil_> > > >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0> > >, boost::fusion::nil_> > >, mpl_::bool_<false> >; R = bool; T0 = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >&; typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type = int]'
/usr/local/include/boost/function/function_template.hpp:1147:5: required from 'typename boost::enable_if_<(! boost::is_integral<Functor>::value), boost::function<R(T0, T1, T2, T3)>&>::type boost::function<R(T0, T1, T2, T3)>::operator=(Functor) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, false>, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, maneuvering::Expr(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type> >, boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, false>, boost::fusion::nil_> > > >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0> > >, boost::fusion::nil_> > >, mpl_::bool_<false> >; R = bool; T0 = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >&; typename boost::enable_if_<(! boost::is_integral<Functor>::value), boost::function<R(T0, T1, T2, T3)>&>::type = boost::function<bool(__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&, boost::spirit::context<boost::fusion::cons<boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >&, boost::fusion::nil_>, boost::fusion::vector<> >&, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >&)>&]'
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:191:19: required from 'static void boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::true_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<const char&>, 0>, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, maneuvering::Expr(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2>&, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<const char&>, 0> >, 2>&, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0> >&>, 2>; Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; T1 = boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >(); T2 = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0>; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::true_ = mpl_::bool_<true>]'
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:229:32: required from 'boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>& boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const Expr&) [with Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<const char&>, 0>, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, maneuvering::Expr(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2>&, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<const char&>, 0> >, 2>&, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0> >&>, 2>; Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; T1 = boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >(); T2 = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0>; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]'
main.cpp:171:47: required from here
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:153:20: error: no matching function for call to 'boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >::variant(const boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >&)'
153 | attr = static_cast<Attribute>(val);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/local/include/boost/variant.hpp:17,
from main.cpp:3:
/usr/local/include/boost/variant/variant.hpp:1770:5: note: candidate: 'boost::variant<T0, TN>::variant(boost::variant<T0, TN>&&) [with T0_ = maneuvering::Nil; TN = {boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > >}]'
1770 | variant(variant&& operand) BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value)
| ^~~~~~~
/usr/local/include/boost/variant/variant.hpp:1770:23: note: no known conversion for argument 1 from 'const boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >' to 'boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >&&'
1770 | variant(variant&& operand) BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value)
| ~~~~~~~~~~^~~~~~~
/usr/local/include/boost/variant/variant.hpp:1759:5: note: candidate: 'boost::variant<T0, TN>::variant(const boost::variant<T0, TN>&) [with T0_ = maneuvering::Nil; TN = {boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > >}]'
1759 | variant(const variant& operand)
| ^~~~~~~
/usr/local/include/boost/variant/variant.hpp:1759:28: note: no known conversion for argument 1 from 'const boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> >' to 'const boost::variant<maneuvering::Nil, boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > > >&'
1759 | variant(const variant& operand)
| ~~~~~~~~~~~~~~~^~~~~~~
/usr/local/include/boost/variant/variant.hpp:1375:5: note: candidate: 'boost::variant<T0, TN>::variant() [with T0_ = maneuvering::Nil; TN = {boost::recursive_wrapper<maneuvering::Expr>, boost::recursive_wrapper<boost::variant<maneuvering::Nil, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::recursive_wrapper<maneuvering::FunctionCall> > >}]'
1375 | variant()
| ^~~~~~~
/usr/local/include/boost/variant/variant.hpp:1375:5: note: candidate expects 0 arguments, 1 provided
This example can be tested here: it is useful to see the whole error message that is cryptic for me and that is useful to debug...
It was broken by Boost.Variant change, filed the issue https://github.com/boostorg/variant/issues/100.
The offending thing is boost::recursive_wrapper<Atom>
, if you replace it with Atom
-- it will compile. https://wandbox.org/permlink/HtUO3QjUI7cO2ySj