-1

I have this type

using expression = boost::make_recursive_variant<
    number,
    std::tuple<
        boost::recursive_variant_,
        binary_operator,
        boost::recursive_variant_
    >
>;

It doesn't matter what binary_operator is, this type doesn't work correctly because of this Using boost::make_recursive_variant with tuple

EDIT: actually i don't know why it doesn't work. It turns out that the pull request mentioned in the answer to the question I linked has been merged to boost 1.56.0, it means the problem lies somewhere else. Here is a minimal program which shows the problem:

#include <boost/variant.hpp>
#include <boost/variant/recursive_variant.hpp>

#include <tuple>

struct A {};
struct B {};

using working_variant = boost::variant<
    A,
    B
>;

using not_working_variant = boost::make_recursive_variant<
    A,
    std::tuple<
        boost::recursive_variant_,
        B,
        boost::recursive_variant_
    >
>;

int main() {
    working_variant x = A();
    not_working_variant y = A();
}

And the compilation error:

$ clang++ -stdlib=libc++ -std=c++14 -isystem ~/soft/boost_1_56_0/ min.cpp 
min.cpp:25:25: error: no viable conversion from 'A' to 'not_working_variant' (aka 'make_recursive_variant<A, std::tuple<boost::recursive_variant_, B,
      boost::recursive_variant_> >')
    not_working_variant y = A();
                        ^   ~~~
/home/crabman/soft/boost_1_56_0/boost/variant/recursive_variant.hpp:176:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from
      'A' to 'const boost::make_recursive_variant<A, std::__1::tuple<boost::recursive_variant_, B, boost::recursive_variant_>, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_> &' for 1st argument
struct make_recursive_variant
       ^
/home/crabman/soft/boost_1_56_0/boost/variant/recursive_variant.hpp:176:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from
      'A' to 'boost::make_recursive_variant<A, std::__1::tuple<boost::recursive_variant_, B, boost::recursive_variant_>, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_> &&' for 1st argument
struct make_recursive_variant
       ^
1 error generated.

So I guess I should rewrite it to use boost::recursive_wrapper instead. But how do I do that? I can't forward-declare a type, which is going to be defined with "using" or "typedef", can I?

CrabMan
  • 1,578
  • 18
  • 37

1 Answers1

1

Disregard all I wrote in the question. Turns out the answer is you need to use ::type to define some type with boost::make_recursive_variant:

using working_variant = boost::variant<
    A,
    B
>;

using working_recursive_variant = boost::make_recursive_variant<
    A,
    B
>::type;

Same works even for code with actual recursion and std::tuple being used.

CrabMan
  • 1,578
  • 18
  • 37