notes/ch16.md
template <typename T> int compare(const T &v1, const T &v2){}template开始,后接模板形参表,模板形参表是用尖括号<>括住的一个或多个模板形参的列表,用逗号分隔,不能为空。class或者typename,这两个关键字含义相同,可以互换使用。旧的程序只能使用class。template <class T, size_t N> void array_init(T (&parm)[N]){}template <typename T> inline T min(const T&, const T&);template <class Type> class Queue {};template <typename T> ret-type Blob::member-name(parm-list)template <typename T> class Bar{friend T;};。typedef引用一个模板,但是新标准允许我们为类模板定义一个类型别名:template<typename T> using twin = pair<T, T>;typename,而不能使用class。template <class T = int> class Numbers{}extern template declaration; // 实例化声明template declaration; // 实例化定义const会被忽略。template <typename T1, typename T2, typename T3> T1 sum(T2, T3);auto val3 = sum<long long>(i, lng); // T1是显式指定,T2和T3都是从函数实参类型推断而来template <typename It> auto fcn(It beg, It end) -> decltype(*beg)标准库的类型转换模板:
type_traits中。对Mod<T>,其中Mod是: | 若T是: | 则Mod<T>::type是: |
|---|---|---|
remove_reference | X&或X&& | X |
| 否则 | T | |
add_const | X&或const X或函数 | T |
| 否则 | const T | |
add_lvalue_reference | X& | T |
X&& | X& | |
| 否则 | T& | |
add_rvalue_reference | X&或X&& | T |
| 否则 | T&& | |
remove_pointer | X* | X |
| 否则 | T | |
add_pointer | X&或X&& | X* |
| 否则 | T* | |
make_signed | unsigned X | X |
| 否则 | T | |
make_unsigned | 带符号类型 | unsigned X |
| 否则 | T | |
remove_extent | X[n] | X |
| 否则 | T | |
remove_all_extents | X[n1][n2]... | X |
| 否则 | T |
T&,则只能传递给它一个左值。但如果是const T&,则可以接受一个右值。T&&,则只能传递给它一个右值。T&&),编译器会推断模板类型参数为实参的左值引用类型。X:
X& &、X& &&和X&& &都折叠成类型X&。X&& &&折叠成X&&。T&&),则它可以被绑定到一个左值上;T&)。move函数是使用右值引用的模板的一个很好的例子。static_cast到一个右值引用是允许的。template <typename T>
typename remove_reference<T>::type&& move(T&& t)
{
return static_cast<typename remove_reference<T>::type&&>(t);
}
forward的新标准库设施来传递参数,它能够保持原始实参的类型。utility中。forward返回显式实参类型的右值引用。即,forward<T>的返回类型是T&&。可变参数模板就是一个接受可变数目参数的模板函数或模板类。
template <typename T, typename... Args>,Args第一个模板参数包。void foo(const T &t, const Args& ... rest);,rest是一个函数参数包。sizeof...运算符,返回参数的数目。forward机制,实现将实参不变地传递给其他函数。template后面跟一个空尖括号对(<>)。