c++ Templates Guide
前言
Type parameters are introduced with either the keyword typename or the keywordclass: The two are entirely equivalent. Templates are functions or classes that are written for one or more types not yet specified. When you use a template, you pass the types as arguments, explicitly or implicitly. Because templates are language features, you have full support of type checking and scope.
Function Templates
- 模版函数参数尽量用引用,以防模版生成过程中,产生局部变量,同时局部变量被返回出来.用指针都不行,临时指针被返回也会有问题.
- 模版函数一般都是inline内联函数,所以模版函数里用到的函数要定义在其之前.
- 历史原因
template <class T>
关键字class
也用于指定类型参数,但是会产生误导(不仅仅只有class类型才能用在template里),所以推荐用关键字typename
- 重载模版函数函数,
template <typename T> inline T const& max (T const& a, T const& b)
,类型指针也是一种重载template <typename T> inline T* const& max (T* const& a, T* const& b)
- Template functions define a family of functions for different template arguments.
- When you pass template arguments, function templates are instantiated for these argument types.
- You can explicitly qualify the template parameters.
- You can overload function templates.
- When you overload function templates, limit your changes to specifying template parameters explicitly. Make sure you see all overloaded versions of function templates before you call them.
- Member function templates cannot be declared
virtual
. In contrast, the ordinary members of class templates can be virtual because their number is fixed when a class is instantiated.
Class Templates
template <typename T1, typename T2>
class MyClass {
...
};
- 模版类的模版函数在被调用才会被编译器加载.如果没有使用,哪怕具体的模版函数在当前文件无法perform也没问题,因为不会被加载.
- 在模版偏特化,如果有一个调用匹配两个模版,则该行为为定义.要解决此ambiguity,需要定义一个更精确定义的偏特模版.
- A class template is a class that is implemented with one or more type parameters left open.
- To use a class template, you pass the open types as template arguments. The class template is then instantiated (and compiled) for these types.
- For class templates, only those member functions that are called are instantiated.
- You can specialize class templates for certain types.
- You can partially specialize class templates for certain types.
template <typename T>
class MyClass<T,int> {
...
};
- You can define default values for class template parameters. These may refer to previous template parameters.
template <typename T1, typename T2 = std::vector<T1>>
class MyClass {
...
};
template <typename T = int, int MAXSIZE = 100>
class Stack {
...
};
- Note especially that, unlike class types, class templates cannot share a name with a different kind of entity:
int C;
class C; // OK: class names and nonclass names are in a different ''space''
int X;
template <typename T>
class X; // ERROR: conflict with variable X
struct S;
template <typename T>
class S; // ERROR: conflict with struct S
Nontype Template Parameters
template <typename T, int MAXSIZE>
class Stack {
...
};
- Templates can have template parameters that are values rather than types.
- You cannot use floating-point numbers, class-type objects, and objects with internal linkage (such as string literals) as arguments for nontype template parameters.
- each template instantiation is its own type.Thus, one cannot be used instead of the other, and you cannot assign one to the other.
- Nontype template parameters stand for constant values that can be determined at compile or link time. The type of such a parameter (in other words, the type of the value for which it stands) must be one of the following:
[a] An integer type or an enumeration type
[b] A pointer type (including regular object pointer types, function pointer types, and pointer-to-member types)
[c] A reference type (both references to objects and references to functions are acceptable)
Tricky Basics
- To access a type name that depends on a template parameter, you have to qualify the name with a leading typename. In general, typename has to be used whenever a name that depends on a template parameter is a type.
template <typename T> class MyClass {
typename T::SubType * ptr;
...
};
- The .template Construct. Without that extra use oftemplate, the compiler does not know that the less-than token (<) that follows is not really “less than” but the beginning of a template argument list. the param