c++boostboost-spiritboost-spirit-qiboost-variant

Updating boost::variant from boost 1.60 to boost 1.79


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...


Solution

  • 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