Introduction:Before the possibilities of the new
C + + language standard,
c++11, the use of
TemplatesWas quite limited if it came to implementing for instance
function Objects (functors)&
Tuple Facilities. Implementing these sort of things using earlier C + + standard often require similiar code to is repeated various times with Out forgetting
Preprocessor metaprogramming. However, thanks to
variadic Templates, programming new features using
Templateshas become
Easier,
clearer& More
memory-efficient.
Although
The D programming languageAlso provides the use of
variadic Templates, only variadic templates offered by C++11 Standard would be covered here, so knowledge of D programming language ' s Variadi C templates is not required in order to read & understand this article. There is assumptions, however, that's the reader of this article understands what class & function templates is & How to declare, define & use them.
What is a variadic template?
Variadic Templateis a template, which can take an arbitrary number of the template arguments of any type. Both the classes & functions can be variadic. Here's a variadic class template:
1 2
|
template<typename... Arguments>class VariadicTemplate;
|
|
Any of the following ways to create a instance of this class template is valid:
1 2 3
|
VariadicTemplate<doublefloat> instance;VariadicTemplate<boolunsignedshortintlong> instance;VariadicTemplate<char, std::vector<int>, std::string, std::string, std::vector<longlong>> instance;
|
|
The number of Variadic template arguments can also is zero, so the following
VariadicTemplate<> instance;
is also valid c++11.
However, if you create a template like this:
1 2
|
template<typenametypename... Arguments>class VariadicTemplate;
|
|
Must set at least one type as a template argument (for
TypeName T), unless default type have been Initilialize D, like in the following declaration:
1 2
|
template<typenameinttypename... Arguments>class VariadicTemplate;
|
|
syntax-the ellipsis operator (...):
The ellipsis operator(...) Is
An operatorUsed in different contexts in C + +. It ' s name comes from an
ellipsis mechanismInch
C. In this mechanism programmer can create a function taking variable number of parameters. Probably the most famous function in both C & C + + to take advantage of this mechanism are
printf-function in
C Standard library:
int printf ( const Char * Format, ...);
ellipsis mechanism can also be used with
preprocessor in a form of a
macro . A macro taking a variable number of parameters is called
a variadic macro .
#define VARIADIC_MACRO (...)
in
C + + , this
ellipsis operator got a new Meaning in different context called
exception handling . The operator is used in
catch blocks after
try blocks :
1 2 3 4 5 6
|
try{ // Try block.}catch(...){ // Catch block.}
|
|
Here, the
ellipsis operator indicates and the
catch block takes in any exception thrown from the
tr Y block as it ' s parameter, no matter the type.
In c++11,
variadic templates brought yet another meaning for this operator. The operator works somewhat like in ellipsis mechanism as already stated, but it's bit more complex:
1 2
|
template<typename... Arguments>void SampleFunction(Arguments... parameters);
|
|
Here ' s a function template. The contents of the Variadic template arguments is called
parameter packs. These packs'll then be unpacked inside the function parameters. For example, if you create a function call to the previous Variadic function template ...
SampleFunction<int, int>(16, 24);
... an equivalent function template would is like this:
1 2
|
template<typenametypename U>void SampleFunction(T param1, U param2);
|
|
syntax-the sizeof ... operator (sizeof ...):another operator Used with variadic templates is
the sizeof ... -operator . Unlike the
sizeof operator, which can be used to determine the size of a type (
for example sizeof (int) or sizeof (double) ),
sizeof ... operator can used to determine the amount of types given into a variadic template. This can is achieved like this:
1 2 3 4 5
|
template<typename... Arguments>class VariadicTemplate{private: staticconstunsignedshortintsizeof...(Arguments);};
|
|
syntax-two ellipsis operators Together (...):In some circumstances, there can is both ellipsis operators put together
(...). These-operators can also be separated
(written as ...).
Probably the most clear-from, however, is to separate these-operators with a comma
(...). Both ways with a comma or without a comma is acceptable.
This kind of syntax can appear with variadic function templates using ellipsis mechanism:
1 2 3 4
|
template<typename... Arguments>void SampleFunction(Arguments......){}
|
|
As already stated, these, ellipsis operator put together can be written differently, so the following examples
1 2 3 4
|
template<typename... Arguments>void SampleFunction(Arguments... ...){}
|
|
1 2 3 4
|
template<typename... Arguments>void SampleFunction(Arguments..., ...){}
|
|
work as well.
Author ' s Opinions & Thoughts: for the sake of readability, use the last method to mark the other Follo Wing ellipsis operators. The previous alternatives may be found confusing and/or cumbersome. Some may find it a matter of taste, though.
Uses of Variadic templates-inheritance & initialization lists:When it comes to classes, variadic templates can be used with
inheritance &
initialization lists. Inheritance taking advantage of variadic templates can be accomplished as this:
1 2
|
template<typename... BaseClasses>classpublic BaseClasses...
|
|
And, if we want to create a constructor inside this class using initialization list to call the constructors of all the GI Ven base classes As template arguments, we have the to do it the This is:
1 2 3 4 5 6 7
|
template<typename... BaseClasses>classpublic BaseClasses...{public: VariadicTemplate(BaseClasses&&... base_classes) : BaseClasses(base_classes)...{ }};
|
|
As can see there's a new operator introduced in C++11 in the constructor ' s parameter list-an
rvalue operator (&A mp;&), which allows
rvalue references. This article isn't intended to cover the use of this operator, if information how to use this operator (
& RV Alue referencesin general), please follow this link:
http://thbecker.net/articles/rvalue_references/section_01.html
Uses of Variadic templates-variadic class template specialization:Like class templates, Variadic class templates can also is specialized. With templates, the specialization happens like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
template<typename T>class Template{public: void SampleFunction(T param){ }};template<>class Template<int>{public: void SampleFunction(int param){ }};
|
|
But with variadic templates it's like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
template<typename... Arguments>class VariadicTemplate{public: void SampleFunction(Arguments... params){ }};template<>class VariadicTemplate<doubleintlong>{public: void SampleFunction(doubleintlong param3){ }};
|
|
Caution: Some compilers may not support Variadic class template specialization yet, or their implementat Ion may somewhat incomplete.
See also: If You is interested in seeing a c++11 standard class template utilizing variadic templates A look at already mentioned
tuples from the link below:
http://www.cplusplus.com/reference/std/tuple/tuple/
Another field where variadic templates may come in handy is
delegates. If you is already familiar with
managed C + + and/or
C #, picking up C + + delegates May is not a problem. You might find good use for them in C + + anyway.
C++11:variadic templates (variable parameter template)