Meta functions for sequences of exponents of 2 I have implemented some meta functions to create sequence for exponents of 2. I would love to know if there is any way to make the code more optimized.
Note: int main() should not be modified. From the requirements of my school:

This program must implement three definitions: sequence&lt;Ts...&gt;, print() and printing_type().

Hence, the name of functions should not be modified.
#include&lt;iostream&gt;

template&lt;size_t... Ts&gt;
struct int_seq{}; 

template&lt;size_t TCount, size_t...Ts&gt;
struct sequence
{
    using type = typename sequence&lt;TCount - 1,  1, (2 * Ts)...&gt;::type;
};

template&lt;size_t...Ts&gt;
struct sequence&lt;0, Ts...&gt;
{
    using type = int_seq&lt;Ts...&gt;;
};

template&lt;size_t TCount&gt;
using create_int_seq  = typename sequence&lt;TCount + 1&gt;::type;

template &lt;typename T&gt;
void print(T val)
{
    std::cout &lt;&lt; val &lt;&lt; &quot; &quot;;
}

template &lt;typename T, typename... Ts&gt;
void print(T val, Ts... t)
{
    std::cout &lt;&lt; val &lt;&lt; &quot; &quot;;
    print(t...);
}

template &lt;
    template &lt;size_t...&gt; class T,
    size_t... S
&gt;
void printing_type(T&lt;S...&gt;)
{
    print(S...);
}

int main()
{
    constexpr size_t N = 63;
    create_int_seq&lt;N&gt; dum{};
    printing_type(dum);
}
Certainly your definitions of printing_type and print could be shortened. You're currently doing
print(t...)  // print(a,b,c,d)

but what you actually want to happen is
print(t)...  // print(a), print(b), print(c), print(d)

So then you have to do a bunch of extra work to transform the former into the latter. Instead of all that extra work, you could just write
void print(size_t val) {
    std::cout &lt;&lt; val &lt;&lt; &quot; &quot;;
}

template&lt;template&lt;size_t...&gt; class T, size_t... S&gt;
void printing_type(T&lt;S...&gt;) {
    (print(S) , ...);
}

Notice that the single-argument print doesn't have to be a template, because val is always a size_t.
In fact, we can inline print into printing_type if we want:
template&lt;template&lt;size_t...&gt; class TT, size_t... Values&gt;
void printing_type(TT&lt;Values...&gt;) {
    ((std::cout &lt;&lt; Values &lt;&lt; &quot; &quot;) , ...);
}

The (ts , ...) syntax is a C++17 fold-expression. If you aren't on C++17, then you can use an initializer list to accomplish the same thing:
template&lt;template&lt;size_t...&gt; class TT, size_t... Values&gt;
void printing_type(TT&lt;Values...&gt;) {
    int dummy[] = {
        ((std::cout &lt;&lt; Values &lt;&lt; &quot; &quot;), 0) ...
    };
}


Your definition for sequence is pretty confusing. Your code could benefit from some unit tests. Compile-time unit tests are easy:
static_assert(std::is_same&lt;create_int_seq&lt;0&gt;, int_seq&lt;1&gt;&gt;::value, &quot;&quot;);
static_assert(std::is_same&lt;create_int_seq&lt;1&gt;, int_seq&lt;1,2&gt;&gt;::value, &quot;&quot;);
static_assert(std::is_same&lt;create_int_seq&lt;2&gt;, int_seq&lt;1,2,4&gt;&gt;::value, &quot;&quot;);
static_assert(std::is_same&lt;create_int_seq&lt;3&gt;, int_seq&lt;1,2,4,8&gt;&gt;::value, &quot;&quot;);
static_assert(std::is_same&lt;create_int_seq&lt;4&gt;, int_seq&lt;1,2,4,8,16&gt;&gt;::value, &quot;&quot;);

As a bonus, these five lines serve as excellent documentation about what this code does... to the extent that I no longer mind the lack of code comments explaining how it might work.
FWIW, if I wanted to make these test cases pass, I'd implement create_int_seq like this:
template&lt;class&gt; struct powers_of_two;
template&lt;size_t... Is&gt;
struct powers_of_two&lt;std::index_sequence&lt;Is...&gt;&gt; {
    using type = int_seq&lt;(size_t(1) &lt;&lt; Is)...&gt;;
};

template&lt;size_t N&gt;
using create_int_seq =
    typename powers_of_two&lt;std::make_index_sequence&lt;N+1&gt;&gt;::type;

Relevant blog post of mine: &quot;Template metaprogramming: Iteration is better than recursion&quot; (July 2018).