Search code examples
c++c++17template-meta-programmingboost-hana

How to convert a boost::hana::tuple into a std::variant


I have the following code where I want to convert a boost::hana::tuple into a std::variant

namespace hana = boost::hana;

template <typename Tuple>
struct to_variant;

template <typename... Ts>
struct to_variant<std::tuple<Ts...>>
{
    using type = std::variant<Ts...>;
};

auto my_tuple = hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<float>);

using my_variant = typename to_variant<my_tuple>::type;

But I always get the error message

error: type/value mismatch at argument 1 in template parameter list for 'template<class Tuple> struct to_variant'
using my_variant = typename to_variant<my_tuple>::type;

I tried to replace std::tuple with hana::tuple with the same result.


Solution

  • I suggest three corrections in your code (two are already addressed in the other answer):

    • Use decltype(my_tuple) to pass a type into to_variant
    • Inside to_variant, use using type = std::variant<typename Ts::type...> to extract the types out of the Hana type_c's.
    • Use a hana::tuple in the specialization, not a std::tuple. More in general, you could also use a template template parameter here.

    Here is the corresponding code:

    namespace hana = boost::hana;
    
    template <typename Tuple>
    struct to_variant;
    
    template <typename... Ts>
    struct to_variant<hana::tuple<Ts...>>
    {
        using type = std::variant<typename Ts::type...>;
    };
    
    auto my_tuple = hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<float>);
    
    using my_variant = typename to_variant<decltype(my_tuple)>::type;