Permuting a typelist Given a typelist, return a typelist of all the permutations of it. For example:

using Types = typelist&lt;char, int, double&gt;;
using Permutations = typelist&lt;
    typelist&lt;char, int, double&gt;,
    typelist&lt;char, double, int&gt;,
    typelist&lt;int, char, double&gt;,
    typelist&lt;int, double, char&gt;,
    typelist&lt;double, char, int&gt;,
    typelist&lt;double, int, char&gt;
    &gt;;

static_assert(std::is_same&lt;permute_t&lt;Types&gt;, Permutations&gt;{}, "!");


There are two different ways of writing metafunction "overloads": partial specialization or function overloading. I'm still unsure of which is "better", and in this solution I ended up using both, which strikes me as questionable. 

The algorithm here is: the permutations of a list is the concatenation of (each element in the list prepended to all the permutations of the list with that element removed).

template &lt;class...&gt; struct typelist { };
template &lt;class T&gt; struct tag { using type=T; };

// remove first instance of type from a typelist
template &lt;class T, class... Ts, class... Rs&gt;
auto remove_first(tag&lt;T&gt;, typelist&lt;T, Ts...&gt;, typelist&lt;Rs...&gt;)
    -&gt; tag&lt;typelist&lt;Rs..., Ts...&gt;&gt;;

template &lt;class T, class F, class... Ts, class... Rs&gt;
auto remove_first(tag&lt;T&gt;, typelist&lt;F, Ts...&gt;, typelist&lt;Rs...&gt;)
    -&gt; decltype(remove_first(tag&lt;T&gt;{}, typelist&lt;Ts...&gt;{}, typelist&lt;Rs..., F&gt;{}));

template &lt;class T, class TL&gt;
using remove_first_t = typename decltype(remove_first(tag&lt;T&gt;{}, TL{}, typelist&lt;&gt;{}))::type;

// concatenate lots of typelists into one typelist
template &lt;class TL&gt;
auto concat(TL ) -&gt; tag&lt;TL&gt;;

template &lt;class... A, class... B, class... Cs&gt;
auto concat(typelist&lt;A...&gt;, typelist&lt;B...&gt;, Cs... cs)
    -&gt; decltype(concat(typelist&lt;A..., B...&gt;{}, cs...));

template &lt;class... Ts&gt;
using concat_t = typename decltype(concat(Ts{}...))::type;

// prepend a type onto a typelist of typelists
template &lt;class T, class... TLs&gt;
auto prepend(tag&lt;T&gt;, typelist&lt;TLs...&gt;)
    -&gt; tag&lt;typelist&lt;concat_t&lt;typelist&lt;T&gt;, TLs&gt;...&gt;&gt;;

template &lt;class T, class TL&gt;
using prepend_t = typename decltype(prepend(tag&lt;T&gt;{}, TL{}))::type;

// get all the permutations of a typelist
template &lt;class T, class=void&gt;
struct permute : tag&lt;typelist&lt;T&gt;&gt; { };

template &lt;class T&gt;
using permute_t = typename permute&lt;T&gt;::type;

template &lt;class... Ts&gt;
struct permute&lt;typelist&lt;Ts...&gt;, std::enable_if_t&lt;(sizeof...(Ts)&gt;1)&gt;&gt;
    : tag&lt;
        concat_t&lt;
            prepend_t&lt;
                Ts,
                permute_t&lt;remove_first_t&lt;Ts, typelist&lt;Ts...&gt;&gt;&gt;
            &gt;...
        &gt;
    &gt;
{ };
You might have some bug in the algorithm.

"testdata"

struct A {};
struct B {};
struct C {};
struct D {};

using Types = typelist&lt;A, B, C, D&gt;;
using Permutations = typelist&lt;
    typelist&lt;A,B,C,D&gt;,
    typelist&lt;A,B,D,C&gt;,
    typelist&lt;A,C,B,D&gt;,
    typelist&lt;A,C,D,B&gt;,
    typelist&lt;A,D,B,C&gt;,
    typelist&lt;A,D,C,B&gt;,
    typelist&lt;B,A,D,C&gt;,
    typelist&lt;B,A,C,D&gt;,
    typelist&lt;B,C,D,A&gt;,
    typelist&lt;B,C,A,D&gt;,
    typelist&lt;B,D,C,A&gt;,
    typelist&lt;B,D,A,C&gt;,
    typelist&lt;C,A,B,D&gt;,
    typelist&lt;C,A,D,B&gt;,
    typelist&lt;C,B,A,D&gt;,
    typelist&lt;C,B,D,A&gt;,
    typelist&lt;C,D,A,B&gt;,
    typelist&lt;C,D,B,A&gt;,
    typelist&lt;D,A,C,B&gt;,
    typelist&lt;D,A,B,C&gt;,
    typelist&lt;D,B,C,A&gt;,
    typelist&lt;D,B,A,C&gt;,
    typelist&lt;D,C,B,A&gt;,
    typelist&lt;D,C,A,B&gt;
&gt;;
static_assert(std::is_same&lt;permute_t&lt;Types&gt;, Permutations&gt;{}, "!");


results in:

prog.cpp:90:1: error: static assertion failed: !
 static_assert(std::is_same&lt;permute_t&lt;Types&gt;, Permutations&gt;{}, "!");
 ^