c++tuplesc++17typelist

C++:Adding an element to a tuple


I am going through the custom implementation for tuples , which is described in C++ template second edition. I need a help to understand how the pushFront actually work. What are the steps that compiler does in order to put the new element in the start of the tuple

template <typename... Elements>
class Typelist
{
};

template <typename... Elements, typename NewElement>
class PushFrontT<Typelist<Elements...>, NewElement> {
 public:
  using Type = Typelist<NewElement, Elements...>;
};

template <typename List, typename NewElement>
using PushFront = typename PushFrontT<List, NewElement>::Type;

template <typename... Types, typename V>
PushFront<Tuple<Types...>, V> 
pushFront(Tuple<Types...> const& tuple, V const& value)
{
  return PushFront<Tuple<Types...>, V>(value, tuple);
}

In the above piece of code, how actually , does the last line work? "PushFront<Tuple<Types...>, V>(value, tuple);"

How from PushFront<Tuple<Types...>, V> , we get a tuple in which pass as head the value and as tail the existing tuple?


Solution

  • I scratched my head so much reading that example that I went and hunted down the book. The book is not full of incomprehensible examples, but they're spread out and incrementally implemented. Only a few are shown in the OP's question.

    The first part involving is showing how to use partial specialization to push a type to a variadic utility struct called Typelist:

    template <typename... Elements>
    class Typelist {};
    
    template<typename List, typename NewElement>
    class PushFrontT;
    
    template<typename... Elements, typename NewElement>
    class PushFrontT<Typelist<Elements...>, NewElement> { ... };
    

    Later on the book implements a full Tuple class that includes this constructor:

    Tuple(Head const& head, Tuple<Tail...> const& tail)
    

    And adds a PushFrontT specialization just for Tuple:

    template<typename... Types, typename Element>
    class PushFrontT<Tuple<Types...>, Element> { ... };
    

    So... the answer is that Tuple has a convenient constructor to copy a tuple and add an element to the front, and a utility class that uses partial template specialization to unpack the type list of the tuple and add a type to the front. The OP seemed to reach that conclusion in their answer, but I thought this context would be helpful for anyone who stumbled on this question and got confused like I did.