1) Member function template of ordinary class
class A
{
public:
template<typename T> //类的成员函数模板,//成员函数模板和函数模板长得样子一样!
void func(T tmp);
};
template<typename T>
void A::func(T tmp)
{
cout << tmp << endl;
}
int main()
{
A a;
a.func<double>(56.89);
return 0;
}
2) Member function template of template class
template<class T2>
class A
{
public:
A(T2 arg):arg_(arg){
}
template<typename T> //类的成员函数模板
void func(T tmp);
private:
T2 arg_;
};
//模板类的成员函数模板类外定义方法
template<class T2>
template<typename T>
void A<T2>::func(T tmp)
{
cout << tmp + arg_ << endl;
}
int main()
{
A<int> a1(45);
a1.func<int>(45); //output 90
return 0;
}
3) Explicit instantiation of templates and explicit declarations.
The role of explicit instantiation: in order to prevent multiple .cpp files from generating the same class template and reduce system compilation overhead;
instantiate definitions and instantiate declarations!
template A; //In any one of multiple .cpp files, the instantiation definition [only one]
extern template A; //In other .cpp files, the instantiation declaration [can be multiple], represents This file does not need to be used in instantiation
4) using to define a template alias (the following case is a class template alias that defines a map container)
//using str_map_t = std::map<std::string, T> type;
//The above sentence, It is neither a function template nor a class template. It uses using to define a type alias, also called [type template];
template<class T>
using str_map_t = std::map<std::string, T>; //类型模板,也叫模板别名
int main()
{
str_map_t<int> m1;
m1.insert({
"abc",123});
return 0;
}
4.1) Use typedef to redefine new types in template classes, but you cannot redefine a template! ! ! using can be used, the defined name is called type template;
template //The writing method before C++98
struct A
{ typedef std::map<string, T> mapType; //There must be a typedef, otherwise a compilation error will occur }; int main( ) { A::mapType a1; a1.insert({ “first”,23 }); return 0; }
//typedef int myint_t; //Use typedef to define an alias, just like defining a variable!!!
typedef int( func)(int, int);
using funcptr = int( )(int, int); //With using definition How to write a function pointer
5) Display specified template parameters
template<class T1,class T2,class T3>
T1 func(T2 a, T3 b)
{
return a + b;
}
int main()
{
//auto ret = func(3, 6);这样写不行,因为T1没有类型,必须显示指定;
auto ret = func<int>(3, 6);
cout << ret << endl;
return 0;
}
6) Full specialization of class templates
说明:
必须有泛化版本,才可以有特化版本!!!
特化版本优先被编译;
template<class T> //泛化版本
class A
{
public:
bool compare(const T& tmp)
{
cout << "一般模板" << tmp << endl;
if (tmp > 2.5) return 1;
}
};
template<>
class A<float> //全特化版本,注意float绑定到类A上,注意写法!!!
{
public:
bool compare(const float& tmp)
{
cout << "全特化" <<tmp << endl;
if (tmp > 2.5) return 1;
}
};
int main()
{
A<float> a;
a.compare(4.7); //调用全特化版本
A<int> a2;
a2.compare(40); //泛化版本
return 0;
}
7) Specialize member functions instead of templates
注意:特化成员函数就一个类,这是跟模板类特化的重要区别!!!
class A
{
public:
template<typename T>
void func(T tmp);
};
template<typename T> //成员函数的泛化版本
void A::func(T tmp)
{
cout << "成员函数的泛化版本 " << tmp << endl;
}
template<> //成员函数的特化版本
void A::func(int tmp)
{
cout << "成员函数的特化版本 " << tmp << endl;
}
int main()
{
A a;
a.func<>(6); //调用的是特化版本
a.func<float>(5.3); //调用的是泛化版本
return 0;
}
8) Partial specialization of class templates (that is, local specialization)
//偏特化两方面:1)从模板参数数量上;2)模板参数范围上
template<class T,class U,class W>
class A //泛化类模板
{
public:
A() {
cout << "泛化版本 A constructor" << endl; }
void func(void){
cout << "泛化版本 func" << endl; }
};
template<class U,class W>
class A<int,U,W>
{
public:
A() {
cout << "偏特化版本1 A constructor" << endl; }
void func(void) {
cout << "偏特化版本1 func" << endl; }
};
template<class T, class W>
class A<T, float, W>
{
public:
A() {
cout << "偏特化版本2 A constructor" << endl; }
void func(void) {
cout << "偏特化版本2 func" << endl; }
};
int main()
{
A<char,int,int> a1;
a1.func();//调用的是泛化版本
A<int, int, int> a2;
a2.func();//调用的是特化版本1
return 0;
}
9) The function template is fully specialized, and the function template has no partial specialization.
template<typename T,typename U>
void func(T a, U b)
{
cout << "函数模板泛化 " << a + b << endl;
}
//以下5句代码用于不会执行!!!
template<typename T>
void func<T, double>(T a, double b) //函数模板偏特化,这是不可以的,编译不过去!!!!!!!!
{
cout <<"函数模板偏特化--------------- "<< a + b << endl;
}
template<>
void func<double,double>(double a, double b) //必须有“<double,double>”,如果没有,则本质上是函数重载;
{
cout << "函数模板全特化--- " << a + b << endl;
}
int main()
{
func<int,int>(3, 4.7); //调用的是泛化版本
func<int,double>(4, 2.7);
func<>(3.4, 5.6);//调用的是全特化版本
return 0;
}