编辑器遇到一个模板定于时,不会生成代码,而是在使用的时候生成代码。
所以在声明的时候,就需要知道定义。即函数模板和类模板的成员函数的定义通常放在头文件中。
在一个类模板的作用于内,我们可以直接使用模板名而不必指定模板实参。
template<typename T> using twin = pair<T, unsigned>; twin<string> books; // books是pair<string, unsigned> twin<int> booksNo; // booksNo是pair<int, unsigned>
目的是为了避免在多个文件中实例化相同模板,导致额外开销严重的问题
extern template declaration; //声明 template declaration; //定义
extern template class Blob<string>; template int compare(const int& a, const int& b);
将实参传递给带模板类型的函数形参时,能够自动应用的类型转换只有const转换及数组或函数到指针的转换
template <typename T> T fobj(T, T); template <typename T> T fref(const T&, const T&); int a[10], b[42]; fobj(a, b); // fobj(int* ,int *) fref(a, b); // 错误:数组类型不匹配
如果一个模板直接匹配,而另一个模板要类型转换才能匹配,则优先前者。
如果匹配的重载是提供同样好的匹配的话,按照以下规则判断
规则2样例:
template <typename T> rep (const T &t); template <typename T> rep (T *t); string s("1"); const string* sp = &s; rep(sp); // 这里会调用第二个 // 【const T &t】本质上可以用于所有类型,【T *t】只能用于指针 // 所以第二个更特例化
template <typename... Args> rep (const Args&... rest) { print(debug_rep(rest)...); //如果调用 rep(1, 2, 3, 4); //等价于 print(debug_rep(1), debug_rep(2), debug_rep(3), debug_rep(4)) print(debug_rep(rest...)); //如果调用 rep(1, 2, 3, 4); //等价于 print(debug_rep(1, 2, 3, 4)) }