A typical approach used with variadic templates is to specialize it for one argument with the rest of the arguments being optional (which works recursively). Here’s a rather naïve example which is probably an example of how not to use variadic templates, but it helped me understand variadic templates better.
template<typename... Args> class Test;
// Specialization for 0 arguments
template<> class Test<>
{
};
// Specialization for at least 1 argument
template<typename T1, typename... TRest> class Test<T1, TRest...>
: public Test<TRest...>
{
public:
T1 Data;
// This will return the base type
Test<TRest...>& Rest()
{
return *this;
}
};
void Foo()
{
Test<int> data;
data.Data = 24;
Test<int, int> twovalues;
twovalues.Data = 10;
// Rest() returns Test<int>
twovalues.Rest().Data = 11;
Test<int, int, char*> threevalues;
threevalues.Data = 1;
// Rest() returns Test<int, int>
threevalues.Rest().Data = 2;
// Rest().Rest() returns Test<char*>
threevalues.Rest().Rest().Data = "test data";
}
Please be aware that no one ever writes code like this. There are correct ways to do this that I will write about in this blog. This example was merely for academic purposes.
Update – I’ve written a follow-up blog entry that shows the proper way to use variadic templates.