模板相关的摘录总结

函数模板的实例化

隐式实例化 : 让编译器自己根据实参的类型推导模板参数的类型

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 是用于模板化成员函数的类型参数。在类中定义的类成员函数模板可以用于成员函数的多态性,使成员函数可以适用于不同的数据类型,避免代码的重复编写。调用类成员函数模板时,需要指定模板参数,在编译时会自动生成适用于指定参数类型的成员函数

posted @ 2023-08-22 11:05  wsl-hitsz  阅读(3)  评论(0编辑  收藏  举报