模板相关的摘录总结
函数模板的实例化
隐式实例化 : 让编译器自己根据实参的类型推导模板参数的类型
template<class T>
T Add(const T& a, const T& b)
{
return a + b;
}
int main()
{
int a = 1, b = 2;
cout << Add(a,b) << endl;
}
显示实例化 : 在函数名后的<>中指定模板参数的实际类型
template<class T>
T Add(const T& a, const T& b)
{
return a + b;
}
int main()
{
int a = 1;
double b = 2.2;
cout<<Add<int>(a,b)<<endl;
cout<<Add<double>(a,b)<<endl;
}
非类型模板参数
#include<iostream>
using namespace std;
template<int a,int b>
int add1()
{
return a + b;
}
template<class T,int a,int b>
int add2(T c)
{
return c + a + b;
}
template<unsigned L1,unsigned L2>
int charscmp(const char(&p1)[L1],const char(&p2)[L2])
{
return strcmp(p1, p2);
}
int main()
{
cout << add1<1, 2>() << endl;
cout << add2<int, 1, 2>(5) << endl;
cout << add2<int, 1, 2>(1.6) << endl;
cout << charscmp("test2", "test") << endl;
}
类模版
(1).类模板成员函数,可以写在类模板定义中,这种写在类模板定义中的成员函数会被隐式声明成inline函数
(2).类模板一旦被实例化之后,那么这个模板的每个实例都会有自己版本的成员函数,所以,类模板的成员函数是有模板参数的,因此,如果要把类模板成员函数的定义写到类模板定义的外面,须以关键字template开始,后接模板参数列表,同时,在类模板名后用<>将模板参数列表里的所有模板参数名列出来
(3).一个类模板可能有多个成员函数,当实例化模板以后,后续如果没有使用某个成员函数,则该成员函数不会实例化
template <typename T> //类模板声明
class Stack
{
public:
Stack();
void push(T num);
T pop();
template<typename U> //该成员函数不受T的限制,根据实际U的类型而定
void print(U num)
{
cout<<num<<endl;
}
private:
int top;
T data[SIZE];
}
template void print<int>(int num); //即针对int类型只实例化一次,只生成一个模板函数;
int mian()
{
Stack<int>s1; //调用形式
return 0;
}
非类型参数模版
template<class T,int size = 10>
class myarray
{
public:
void func();
private:
T arr[size];
};
template<class T,int size>
void myarray<T,size>::func()
{
cout << size << endl;
return;
}
类模板的特化
模板的全特化
//全特化
template<>//全特化,由于是全特化,参数都指定了,参数列表故为空。
class Stack<bool> {
private:
std::deque<bool> elems; // 元素
public:
void push(bool const&); // push元素
void pop(); // pop元素
bool top() const; // 传回 stack最顶端元素
bool empty() const { // stack是否为空
return elems.empty();
}
};
void Stack<bool>::push(bool const& elem)
{
elems.push_back(elem); // 追加元素
}
void Stack<bool>::pop()
{
if (elems.empty()) {
throw std::out_of_range("Stack<bool>::pop(): empty stack");
}
elems.pop_back(); // 移除最后一个元素
}
bool Stack<bool>::top() const
{
if (elems.empty()) {
throw std::out_of_range("Stack<bool>::top(): empty stack");
}
return elems.back(); // 传回最后一个元素的拷贝
}
模板的偏特化
#include <iostream>
using namespace std;
template<typename T1,typename T2>//定义模板类
class Test{
public:
Test(T1 i,T2 j):a(i),b(j){cout<<"模板类"<<endl;}
private:
T1 a;
T2 b;
};
template<typename T2> //由于只指定了一部分参数,剩下的未指定的需在参数列表中,否则报错。
class Test<char,T2>{
public:
Test(char i,T2 j):a(j),b(j){cout<<"个数偏特化"<<endl;}
private:
char a;
T2 b;
};
template<typename T1,typename T2> //这是范围上的偏特化
class Test<T1*,T2*>{
public:
Test(T1* i,T2* j):a(i),b(j){cout<<"指针偏特化"<<endl;}
private:
T1* a;
T2* b;
};
template<typename T1,typename T2>//同理这也是范围上的偏特化
class Test<T1 const,T2 const>{
public:
Test(T1 i,T2 j):a(i),b(j){cout<<"const偏特化"<<endl;}
private:
T1 a;
T2 b;
};
int main()
{
int a;
Test<double,double> t1(0.1,0.2);
Test<int,char> t2(1,'A');
Test<char,bool> t3('A',true);
Test<int*,int*> t4(&a,&a);
Test<const int,const int> t5(1,2);
return 0;
}
类成员的函数模版(class member function templates)
#include <iostream>
template <typename T>
class Example {
public:
template <typename U>
void print(T a, U b) {
std::cout << "Arguments are: " << a << " and " << b << std::endl;
}
};
int main() {
Example<int> ex1;
ex1.print(10, "hello");
Example<std::string> ex2;
ex2.print("world", 3.14);
return 0;
}
这里,ClassName 是定义类的名称,T 是用于模板化类的类型参数,U 是用于模板化成员函数的类型参数。在类中定义的类成员函数模板可以用于成员函数的多态性,使成员函数可以适用于不同的数据类型,避免代码的重复编写。调用类成员函数模板时,需要指定模板参数,在编译时会自动生成适用于指定参数类型的成员函数