Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to convert in compile time a `std::make_index_sequence<N>` to `parametrized_type<0,1,2,3,…,N-1>`

I have parametrized with integers a template class

template<unsigned int I> class TemplClass{};

Then I define an template alias for a std::variant:

template<template<unsigned int I> class TC, unsigned int ... Is>
using TC_variant = typename std::variant<TC<Is>...>;

I have coded the ugly (and not easily scalable):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

using my_variant = TC_variant<TemplClass,
     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
    10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
    20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
    30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
    40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
    50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
    60, 61, 62, 63
>; 

And now I want to use std::make_index_sequence<N> to define the same concrete my_variant:

// BAD : IT NOT COMPILES
using my_variant = TC_variant<TemplClass,std::make_index_sequence<64>>; 

This code does not compile because std::integer_sequence<std::size_t, 0, 1, ... ,N-1> is not 0 , 1 , ... , N-1 (pseudocode, not C++). ¿How do this “conversion”?

The code that compiles is:

    #include <variant>
    
    // Template class parametrized with an integer value
    template <unsigned int I> class TemplClass{};
    
    // Template alias for a definition of the 
    // variant template type needed
    template<template<unsigned int I> class TC, unsigned int ...Is>
    using TC_variant = typename std::variant<TC<Is>... >;
    
    // Type that I want to instantiate
    using my_variant = TC_variant<TemplClass,
         0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
        10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
        20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
        30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
        40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
        50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
        60, 61, 62, 63
    >; 

    

>Solution :

Assuming the first alias was supposed to be

template<template<unsigned int I> class TC, unsigned int ... Is>
using TC_variant = typename std::variant<TC<Is>...>;
//                                       ^^^  ^

You can use a type trait to provide the necessary indirection and deduce the pack from the index sequence:

template <template <std::size_t I> class TC, class>
struct TC_variant;

template <template <std::size_t I> class TC, std::size_t... Is>
struct TC_variant<TC, std::index_sequence<Is...>> {
  using type = std::variant<TC<Is>...>;
};

template <template <std::size_t I> class TC, class TSeq>
using TC_variant_t = typename TC_variant<TC, TSeq>::type;

using my_variant = TC_variant_t<TemplClass, std::make_index_sequence<64>>;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading