Template argument deduction (C++11)

Parameter packs can be deduced by template argument deduction in the same way as other normal template parameters. The following example shows how template argument deduction expands packs from a function call:

template<class...A> void func(A...args){}

int main(void){
    func(1,2,3,4,5,6);
    return 0;
}

In this example, the function argument list is (1,2,3,4,5,6). Each function argument is deduced to the type int, so the template parameter pack A is deduced to the following list of types: (int,int,int,int,int,int). With all the expansions, the function template func is instantiated as void func(int,int,int,int,int,int), which is the template function with the expanded function parameter pack.

In this example, if you change the function call statement func(1,2,3,4,5,6) to func(), template argument deduction deduces that the template parameter pack Ais empty:

template<class...A> void func(A...args){}

int main(void){
    func();
    return 0;
}

Template argument deduction can expand packs from a template instantiation, as shown in the following example:

#include <cstdio>

template<int...A> struct container{
    void display(){printf("YIKES\n");}
};

template<int B, int...C> struct container<B,C...>{
    void display(){
        printf("spec %d\n",B);
        container<C...>test;
        test.display();
    }
 };

template<int C> struct container<C>{
    void display(){printf("spec %d\n",C);}
};

int main(void)
{
   printf("start\n\n");
   container<1,2,3,4,5,6,7,8,9,10> test;
   test.display();
   return 0;
} 

The output of this example:

start

spec 1
spec 2
spec 3
spec 4
spec 5
spec 6
spec 7
spec 8
spec 9
spec 10

In this example, the partial specialization of the class template container is template<int B, int...C> struct container<B,C...>. The partial specialization is matched when the class template is instantiated to container<1,2,3,4,5,6,7,8,9,10>. Template argument deduction deduces the template parameter pack C and the parameter B from the argument list of the partial specialization. Template argument deduction then deduces the parameter B to be 1, the pack expansion C... to a list: (2,3,4,5,6,7,8,9,10), and the template parameter pack C to the following list of types:(int,int,int,int,int,int,int,int,int).

If you change the statement container<1,2,3,4,5,6,7,8,9,10> test to container<1> test, template argument deduction deduces that the template parameter pack C is empty.

Template argument deduction can expand packs after the explicit template arguments are found. Consider the following example:

#include <cassert>

template<class...A> int func(A...arg){
    return sizeof...(arg);
}

int main(void){
    assert(func<int>(1,2,3,4,5) == 5);
    return 0;
}

In this example, the template parameter pack A is deduced to a list of types: (int,int,int,int,int) using the explicit argument list and the arguments in the function call.