Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invert tuple arguments

I want to write a template class InvTuple which defines type as a tuple of class arguments in inverse order. So it should work like

InvTuple<T1, T2, T3, ...>::type   --->   tuple<..., T3, T2, T1>

I defined it like so

template<class...T>
struct InvTuple;

template<class T1, class...T>
struct InvTuple < T1, T... >
{
    template<class... U>
    using doInvert = typename InvTuple<T...>::doInvert < U..., T1 > ;  
                     // <--- unrecognizable template declaration/definition, 
                     // syntax error : '<'

    using type = doInvert<>;
};

template<>
struct InvTuple <>
{
    template<class... U>
    using doInvert = tuple<U...>;

    using type = doInvert < > ;
};

But this does not compile due to the error as shown in the code. Please help me to understand what's wrong.

like image 278
Alex B. Avatar asked Oct 09 '14 11:10

Alex B.


1 Answers

You need the template keyword:

using doInvert = typename InvTuple<T...>::template doInvert < U..., T1 > ;

and you also need to switch U... and T1 in the same line to have that work properly:

#include <iostream>
#include <tuple>
#include <typeinfo>
using namespace std; // Don't try this at home

template<class...T>
struct InvTuple;

template<class T1, class...T>
struct InvTuple < T1, T... >
{
    template<class... U>
    using doInvert = typename InvTuple<T...>::template doInvert < T1, U... >;

    using type = doInvert<>;
};

template<>
struct InvTuple <>
{
    template<class... U>
    using doInvert = tuple<U...>;

    using type = doInvert < > ;
};

int main()
{
    InvTuple<int,char,bool> obj;
    InvTuple<int,char,bool>::type obj2;
    cout << typeid(obj).name() << endl; // InvTuple<int, char, bool>
    cout << typeid(obj2).name() << endl; // std::tuple<bool, char, int>
}

Example

like image 152
Marco A. Avatar answered Sep 28 '22 11:09

Marco A.