//重载与模板
//函数模板可以被另一个或普通非模版函数重载,名字相同的函数必须具有不同数量或类型的参数
template<typename T> string debug_rep(const T&)
{/**/}
template<typename T> string debug_rep(T *p)
{/**/}
string debug_rep(const string&)
{/**/}
//编译器会先选择非模板函数版本。
debug_rep<string>(const string &)//使用模板函数
debug_rep(const string &)//使用非模板函数
//模板特例化
//一个特例化版本就是模板的一个独立的定义,在其中一个或多个模版参数被指定为特定的类型
//函数模板特例化
//当我们特例化一个函数模板时,必须为原模板中的每个模板参数都提供实参
//定义一个特例化版本时,函数参数类型必须与一个先前声明的模板中对应的类型匹配。
//使用关键字template后跟一个空尖括号,空尖括号指出我们将为原模板的所有模板参数提供实参
template<typename T> int compare(const T&, const T&);
template<>
int compare(const char* const &p1, const char* const &p2)
{
return strcmp(p1, p2);
}
//类模板特例化
//打开命名空间,以便特例化std::hash
template<class T> class std::hash;
class Class_data {
//因为hash<Class_data>使用了Class_data的私有成员,必须声明为//因为hash<Class_data>使用了Class_data的友元
friend class std::hash<Class_data>;
};
namespace std {
template<>
struct hash<Class_data>
{
typedef size_t result_type;
typedef Class_data argument_type;
size_t operator()(const Class_data& d)const;
};
size_t hash<Class_data>::operator()(const Class_data& d)const
{/**/}
}
//类模板部分特例化
//类模板的特例化不必为所有模板参数提供特例化,可以只指定部分模板参数
//原始版本
template<class T>struct remove_reference {
typedef T type;
};
//部分特例化版本
template<class T>struct remove_reference<T&>//左值引用
{typedef T type;};
template<class T>struct remove_reference<T&&>//右值引用
{typedef T type;};
//特例化成员而不是类
template<typename T>struct Foo {
Foo(const T &t = T()) :mem(t) {}
void Bar() {/**/}
T mem;
};
template<>
void Foo<int>::Bar(){}//特例化Foo<int>的成员Bar
Foo<string> fs;//实例化Foo<string>::Foo()
fs.Bar();//实例化Foo<string>::Bar()
Foo<int> fi;//实例化Foo<int>::Foo()
fi.Bar();//使用特例化版本的Foo<int>::Bar()
来源:51CTO
作者:li_unit
链接:https://blog.csdn.net/li_unit/article/details/100861036