Variadic templates make it easier to create multi-type containers like tuples,
but it appears to be more complicated than I expected.
I assume making C++ templates capable of managing a variable number of types
will generate specialization code for each type in the type-list. The recursive
strategy employed to use Variadic Templates seems to imply this:
// Specialization of myFunc(), used while unpacking type parameter list.
// This is a normal template function, nothing special.
template<typename T> int myFunc(const T& val) {
cout << " myFunc(const T&) : val = " << val << endl ;
return 0;
}
Variadic template function declaration and definition shown below is explained
here:
mArgs contains the type-list, that's what ' typename... mArgs ' is about. The
signature of myFunc() is const T& which is a regular template type declaration,
but const mArgs&... args associates parameter args with the values passed in by
the caller. The three dots or ellipsis ... is a meta-operator. In the
declaration they are on the left side which mean the types in the type-list and
the values passed in by the caller are assigned to mArgs and args respectively.
Inside the function definition notice the ellipsis ... are now on the other
side of args. This mean extract the values from args. In the initial call of
myFunc() the parameter T& val is assigned the first value passed in by the
caller. As each recursive call is made val gets assigned the value extracted by
args... until there is only one left, then the specialization shown above is
called which ends the recursion.
template<typename T, typename... mArgs> int myFunc(const T& val, const
mArgs&... args) {
cout << " myFunc(const T&, const mArgs&...) : val = " << val << endl ;
myFunc(args...);
The three dots ... (meta-operator) extract the values from args until there is
only one left. Then the specialization myFunc(const T&) is called which ends
the recursion.
return 0;
}
The call to the function can be made like this:
myFunc("This is a string",1234,324.50," Another string ");
It appears that each argument passed to myFunc() will cause a specialization to
be generated by the compiler for that type. To create a multi-type container
that's type-safe you need to manage each specializations at run-time. Also, I
was thinking of a strategy that would not require a recursive approach. I guess
the best thing to do is hide the recursive implementation inside a class.
I hope my comment and explanation was well understood.
Thanks,
Jim Smith