Alex B.
Alex B.

Reputation: 368

variadic template of template metaprogramming

To put it simple, let's consider 2 stages.

  1. I define variadic structs variadic1, variadic2, ... and template template applyTo_double_float like so

    template<class...T> 
    struct variadic1;
    
    template<class...T>
    struct variadic2;
    
    template<template<typename...> class Templ>
    struct applyTo_double_float
    {
        typedef Templ<double, float> type;
    };
    

    Having this, the result of e.g. applyTo_double_float<variadic1>::type is variadic1<double,float>, which is fine.

  2. I define template type aliases variadic1_char, variadic2_char, variadic1_int, variadic2_int

    template<class...T>
    using variadic1_char = variadic1 < char, T... > ;
    template<class...T>
    using variadic2_char = variadic2 < char, T... > ;
    
    template<class...T>
    using variadic1_int = variadic1 < int, T... > ;
    template<class...T>
    using variadic2_int = variadic2 < int, T... > ;
    

    Now I can write applyTo_double_float<variadic1_char>::type which gives me variadic1 < char, double,float >. Likewise applyTo_double_float<variadic1_int>::type == variadic1 < int, double,float >, etc.

My question is if it is possible to reduce twice the number of templates from the stage 2 (4 pieces) and generalize it with the help of 2 template-template-template-s, namely magicVariadic1, magicVariadic2 to be able to write something like applyTo_double_float<magicVariadic1<char>>::type instead of applyTo_double_float<variadic1_char>::type.

Or maybe even it's possible to introduce one superMagic template which will replace all templates from stage 2 and allow to write e.g applyTo_double_float<superMagic<variadic1, char>>::type instead of applyTo_double_float<variadic1_char>::type etc. Thanks for answers.

Upvotes: 2

Views: 347

Answers (1)

R Sahu
R Sahu

Reputation: 206577

This seems to work for me:

#include <iostream>
#include <typeinfo>

template<class...T> 
struct variadic1 {};

template<template<typename...> class Templ>
struct applyTo_double_float
{
    typedef Templ<double, float> type;
};

template<class T1>
struct variadic1_magic
{
   template<class...T> struct inner
   {
      typedef variadic1<T1, T...> type;
   };
};

int main()
{
   typedef applyTo_double_float<variadic1_magic<char>::inner>::type Type1;
   std::cout << typeid(Type1).name() << std::endl;
   return 0;
}

Update

A better solution, thanks to @dyp:

template<template<class...> class TT, class... U>
struct super_magic
{
   template<class... V>
      struct inner
      {
         using type = TT<U..., V...>;
      };
};

int main()

{
   using Type1 = applyTo_double_float< super_magic<variadic1, char>::inner >::type;
   std::cout << typeid(Type1).name() << std::endl;

   return 0;
}

Upvotes: 2

Related Questions