C++11 : variadic templates(可变参数模板)
2015-05-09 15:11
232 查看
Introduction:
Before the possibilities of the new C++ language standard, C++11, the use of templates was quite limited when 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 be repeated various times without forgetting preprocessor metaprogramming. However, thanks to variadic templates, programming new features using templates has become easier, clearer & more memory-efficient.Although the D programming language also provides the use of variadic templates, only variadic templates offered by C++11 standard will be covered here, so knowledge of D programming language's variadic templates is not required in order to read & understand this article. There are assumptions, however, that the reader of this article understands what class & function templates are & how to declare, define & use them.
What is a variadic template?
Variadic template is a template, which can take an arbitrary number of 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; |
1 23 | VariadicTemplate<double, float> instance; VariadicTemplate<bool, unsigned short int, long> instance; VariadicTemplate<char, std::vector<int>, std::string, std::string, std::vector<long long>> instance; |
VariadicTemplate<> instance;
is also valid C++11.
However, if you create a template like this:
1 2 | template<typename T, typename... Arguments> class VariadicTemplate; |
1 2 | template<typename T = int, typename... Arguments> class VariadicTemplate; |
Syntax - the ellipsis operator (...):
The ellipsis operator (...) is an operator used in different contexts in C++. It's name comes from an ellipsis mechanism in 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 is 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 23 | try{ // Try block. } catch(...){ // Catch block. } |
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); |
SampleFunction<int, int>(16, 24);
...an equivalent function template would be like this:
1 2 | template<typename T, typename 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 be used to determine the amount of types given into a variadic template. This can be achieved like this:1 23 | template<typename... Arguments> class VariadicTemplate{ private: static const unsigned short int size = sizeof...(Arguments); }; |
Syntax - two ellipsis operators together (......):
In some circumstances, there can be two ellipsis operators put together (......). These two operators can also be separated (written as ... ...).Probably the most clear way, however, is to separate these two operators with a comma (..., ...). Both ways with a comma or without a comma are acceptable.
This kind of syntax can appear with variadic function templates using ellipsis mechanism:
1 23 | template<typename... Arguments> void SampleFunction(Arguments......){ } |
1 23 | template<typename... Arguments> void SampleFunction(Arguments... ...){ } |
1 23 | template<typename... Arguments> void SampleFunction(Arguments..., ...){ } |
Author's opinions & thoughts: For the sake of readability, use the last method to mark the two following 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 like this:1 2 | template<typename... BaseClasses> class VariadicTemplate : public BaseClasses... |
1 23 | template<typename... BaseClasses> class VariadicTemplate : public BaseClasses...{ |
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 be specialized. With templates, the specialization happens like this:1 23 | template<typename T> class Template{ public: void SampleFunction(T param){ } }; template<> class Template<int>{ public: void SampleFunction(int param){ } }; |
1 23 | template<typename... Arguments> class VariadicTemplate{ public: void SampleFunction(Arguments... params){ } }; template<> class VariadicTemplate<double, int, long>{ public: void SampleFunction(double param1, int param2, long param3){ } }; |
Caution: Some compilers may not support variadic class template specialization yet, or their implementation may be somewhat incomplete.
See also:
If you are interested in seeing a C++11 standard class template utilizing variadic templates, please take a look at already mentioned tuple 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 are already familiar with managed C++ and/or C#, picking up C++ delegates may not be a problem. You might find good use for them in C++ anyway.
相关文章推荐
- c++11 之可变参数模板
- c++11 可变参数模板函数
- c++11 可变参数模板
- C++11:可变参数模板实现print输出参数
- C++11 可变参数模板
- c++11可变参数模板
- C++11 可变参数模板
- C++11新特性之五——可变参数模板
- C++11标准新增可变参数模板(variadic template)
- 使用C++11的可变参数模板改造单例模式
- C++11新特性:可变参数模板
- C++11标准之variadic template (可变参数模板)
- c++11——可变参数模板
- C++11标准新增可变参数模板(variadic template)
- c++11中的可变参数模板
- C++11 可变参数模板
- C++11之右值引用(一):从左值右值到右值引用
- C++11中的右值引用及move语义编程
- c++11 FAQ
- C++11多线程——lock详解