Is it possible to generate a variant from an integer sequence?

Viewed 70

Would it be possible to generate a variant from an integer sequence like in this pseudo C++ sample:

#include <utility>
#include <variant>

template <int MyInt>
struct MyStruct{};

using MyIntegerSequence = std::make_integer_sequence<int, 3>;

using MyVariant = std::variant<MyStruct<MyIntegerSequence>...>; // Does not compile

int main()
{
    return sizeof(MyVariant);    
}

On coliru: http://coliru.stacked-crooked.com/a/2439048b107642c2

1 Answers

It's possible, sure. The key is that one must use a pack expansion of some sort. Your struct takes an int non-type template parameter. So we must expand the integer sequence's pack to feed them into MyStruct one at a time.

MyStruct<MyIntegerSequence>... is not a pack expansion, since there is no template definition and no pack in that context.

For example, with a class template (and partial specialization):

template<typename Seq> struct MyVariantHelper;

template<int... Is> struct MyVariantHelper<std::integer_sequence<int, Is...>> {
    using type = std::variant<MyStruct<Is>...>;
};

using MyVariant = MyVariantHelper<MyIntegerSequence>::type;

Or with a function template and decltype:

template<int... Is>
auto MyVariantHelper(std::integer_sequence<int, Is...>) 
  -> std::variant<MyStruct<Is>...>;

using MyVariant = decltype(MyVariantHelper(MyIntegerSequence{}));
Related