1.一个简单的类模板代码
namespace Test {
template<typename T>
class Vector {
public:
void push_back(const T& t) {
m_vector.push_back(t);
}
void pop() {
m_vector.pop_back();
}
T const& top() {
return m_vector.back();
}
private:
std::vector<T> m_vector;
};
}
注意:编译器在模板中的报错不一定实际上的错误!
分文件编写类模板
//A.hpp
template<typename T>
class A {
public:
A() = default;
A(const A<T>&);
A const& operator=(const A<T>&);
void func();
};
template<typename T>
A<T>::A(const A<T>& t) {
std::cout << "构造函数" << std::endl;
}
template<typename T>
A<T>const& A<T>::operator=(const A<T>&) {
std::cout << "operator =" << std::endl;
}
template<typename T>
void A<T>::func() {
std::cout << "func" << std::endl;
}
3.std::type_triats提供很多接口
template<typename T>void B(const T&t) {
if constexpr (std::is_default_constructible_v<T>) {
std::cout << "有默认构造函数" << std::endl;
}
};
4.模板特化
template<>
class A<std::string> {
std::deque<std::string> m_deque;
public:
A() = default;
void func();
void Lee();
//A(const A<std::string>&);
//A(A<std::string>&&);
};
//A<std::string>::A(const A&) {
// std::cout << "拷贝构造函数" << std::endl;
//}
void A<std::string>::func() {
std::cout << "fun" << std::endl;
}
void A<std::string>::Lee() {
std::cout << "special" << std::endl;
}
5.部分特化
template<typename T>class A<T*>{
}
6.多参数特化
template<typename T1,typename T2>class B{
}
template<typename T>class B<T,T>{
}
template<typename T>class B<T,int>{
}
template<typename T1,typename T2>B<T1*,T2*>{
}
7.类模板默认参数
template<typename T, typename Cont = std::vector<T>>class B {
private:
Cont elems;
public:
void push_back(const T&t);
void pop();
const T& top() const;
};
template<typename T,typename Cont>
void B<T, Cont>::pop() {
elems.pop_back();
}
template<typename T,typename Cont>
void B<T, Cont>::push_back(const T& t) {
elems.push_back(t);
}
template<typename T,typename Cont>
const T& B<T, Cont>::top() const{
return elems.back();
}
8.类型别名
typedef Stack<int> IntStack;
IntStack stack;
9.模板别名
template<typename T>
using C = B<T,std::deque<T>>;
10.类模板成员别名
template<typename Iterator>
struct Cap {
using it = Cap<Iterator>;
using It = typename Iterator*;
Iterator a;
};
template<typename T>
using It = typename Cap<T>::it;
template<typename T>
using Ptr = typename Cap<T>::It;
11.类模板推导
//Memeber memeber = 0;
//这里T被推导为int
template<typename T>
class Member {
public:
Member(T t) :m_vector({ t }) {
}
private:
std::vector<T> m_vector;
};
12.类模板推导字符串
template<typename T>
class MString {
public:
std::vector<T> m_vector;
public:
MString(T t) :m_vector({ t }) {//这里会退化为char*
}
void push_back(const T&t){
m_vector.push_back(t);
}
};
13.推导指引
class MString {
public:
std::vector<T> m_vector;
public:
MString(T t) :m_vector({ t }) {
}
void push_back(const T&t){
m_vector.push_back(t);
}
};
//template<>
//class MString<std::string> {
//public:
// MString(const char*) {
// std::cout << "std::string 特化版本调用" << std::endl;
// }
//
//};
MString(const char*)->MString<std::string>;
14.推到指引的实际作用模板化聚合
template<typename T> struct Aggregates {
T value;
std::string id;
};
Aggregates(const char*,const char*)->Aggregates<std::string>;//这里这个指引起到构造函数的作用,使编译器能够推导模板类型(c++17后)