Typelist with extractor The purpose of the code is to store arbitrary number of types. The type can be extracted from it using Extract template, which uses template recursion to get the needed type. There will be compilation error if user will try to get out of bounds. I think it supports both fully defined types and only declared types. 

In which ways the code below can be improved?

#ifndef TYPELIST_H
#define TYPELIST_H

#include &lt;cstddef&gt;

struct NullType;

template &lt;typename Head, typename ... Tail&gt;
struct TypeList
{
    using head = Head;
    using tail = typename TypeList&lt;Tail...&gt;;
};

template &lt;typename Single&gt;
struct TypeList &lt;Single&gt;
{
    using head = Single;
    using tail = NullType;
};

template &lt;size_t index, typename typelist&gt;
struct Extract
{
    using result = typename Extract&lt;index - 1, typename typelist::tail&gt;::result;
};

template &lt;typename typelist&gt;
struct Extract &lt;0, typelist&gt;
{
    using result = typename typelist::head;
};

#endif


I doubted about whether or not make NullType declaration only. In my opinion, leaving definition better says "don't use this" than empty definition. 

I was thinking about SFINAE on out of range indexes, but thought the behavior will be surprising. 

My another concern was creating objects of such classes. I couldn't figure out the way to restrict users from creating the objects. The only thing that came to mind is deleting all constructors, but it is strange, thus I decided to refrain from deleting constructors.

Example usage:

#include "typelist.h"
#include &lt;typeinfo&gt;
#include &lt;iostream&gt;

int main()
{
    using MyList = TypeList&lt;int, char, bool&gt;;
    using extracted = Extract&lt;2, MyList&gt;::result;

    std::cout &lt;&lt; (typeid(extracted) == typeid(bool));
}
Naming

Templates depend on a consistent naming scheme for static polymorphism.

We can observe such consistent naming throughout the type traits offered by the standard library (from std::aligned_storage to std::add_pointer); the two most common names being:


A type alias member when the type trait produces a type result.
A value static data member to represent constexpr values.


This means that naming your extracted type alias as result is non-standard and breaks with any templates that assume the same naming convention from the standard library.

What is a type list?

There doesn't seem to be a specific purpose for having a type list that is defined in terms of a head and tail when variadic templates can easily represent what a type list is. Thus, we can simply define a type list as:

template &lt;class... Types&gt;
class type_list {};


What is extracting from a type list?

We can define a more general extraction template to extract from a variadic template.

template &lt;std::size_t idx, class... Types&gt;
class extract
{
    static_assert( idx &lt; sizeof...( Types ), "index out of bounds" );

    template &lt;std::size_t i, std::size_t n, class... Rest&gt;
    struct extract_impl;

    template &lt;std::size_t i, std::size_t n, class T, class... Rest&gt;
    struct extract_impl&lt;i, n, T, Rest...&gt;
    {
        using type = typename extract_impl&lt;i + 1, n, Rest...&gt;::type;
    };

    template &lt;std::size_t n, class T, class... Rest&gt;
    struct extract_impl&lt;n, n, T, Rest...&gt;
    {
        using type = T;
    };

public:
    using type = typename extract_impl&lt;0, idx, Types...&gt;::type;
};


Now that we have that, extracting from our type list is a simple subset operation based on the generalized template for extraction:

template &lt;std::size_t idx, class TypeList&gt;
struct type_list_extract;

template &lt;std::size_t idx, template &lt;class...&gt; class TypeList, class... Types&gt;
struct type_list_extract&lt;idx, TypeList&lt;Types...&gt;&gt;
{
    using type = typename extract&lt;idx, Types...&gt;::type;
};


For which we can provide a convenience alias:

template &lt;std::size_t idx, class TypeList&gt;
using type_list_extract_t = typename type_list_extract&lt;idx, TypeList&gt;::type;


That we can now use as follows:

int main()
{
    using list_t = type_list&lt;char, bool, void&gt;;

    static_assert( std::is_same&lt;char, type_list_extract_t&lt;0, list_t&gt;&gt;::value, "!" );
    static_assert( std::is_same&lt;bool, type_list_extract_t&lt;1, list_t&gt;&gt;::value, "!" );
    static_assert( std::is_same&lt;void, type_list_extract_t&lt;2, list_t&gt;&gt;::value, "!" );
    //type_list_extract_t&lt;3, list_t&gt;; // static_assert fails: index out of bounds
}


Final words

There are non-recursive ways to implement extraction (among other operations); they will most likely (possibly definitely!) require integer/index sequences. You can have a look at my answer for this question to see a non-recursive integer sequence implementation.

There are many more cool tricks to do with templates. Look on this very site or Stack Overflow!