1.关键字typename 关键字typename声明的是一个类型 示例代码如下
namespace Lee {
class B {
public:
};
class A {
public:
using Sub = B;
};
template<typename T>class C {
public:
typename T::Sub* ptr;//重点
};
}
2.默认初始化 代码如下
void foo(){
int a;
int*ptr;}
c++会给内置类型例如指针,整数等等初始化一个默认值 还可以这么做
template<typename T>
class B {
public:
//B() :t{} {
//
//}
T t;
};
template<typename T>
class A {
public:
A() :b{} {//在c++17及之后可以用花括号的方式来初始化成员
}
B<T> b;
};
注意事项: 1.不能用于初始化静态成员对象
template<typename T>class MyClass{
private:
T t{};//注意用于非静态对象
}
2.不能直接用于模板默认参数
template<typename T>void foo(T t{})//错误的
template<typename T>void foo(T t = T{});//正确的
3.使用this->
template<typename T>
class A {
public:
A() = default;
void f() {
std::cout << "A" << std::endl;
}
};
template<typename T>class B :public A<T> {
public:
B() = default;
void func() {
std::cout << "B func called" << std::endl;
this->f();
A<T>::f();//如果不采用这两种方式调用f,永远调用不了f函数
}
};
4.对于模板的数组和字符串使用 代码
template<typename T,size_t size>
void Array(const T(array)[size]) {
std::cout << "value Array" << std::endl;
}
template<typename T,size_t size>
void Array(const T(&array)[size]) {
std::cout << "reference Array" << std::endl;
}
template<typename T>
void Array(const T* array) {
std::cout << "pointer" << std::endl;
}
//很奇怪,对于int a[5],Array(a)调用的都是引用版本,感觉像是编译器做的优化
5.成员模板
class Member {
public:
Member() = default;
template<typename T>void func(T t) {
std::cout << "模板默认版本" << std::endl;
}
};
template<> inline void Member::func<std::string>(std::string s) {
std::cout << "特化的std::string 版本" << std::endl;
}
template<> inline void Member::func<int>(int a) {
std::cout << "特化的int 版本" << std::endl;
}
//类成员模板和函数模板一样只能全特化,不能偏特化,写法都一样
//函数模板
template<typename T>
void func(T t) {
}
template<>inline void func<std::string>(const std::string s) {
}
6.关于成员模板的概念
- 成员模板可以用于operator和构造函数,移动构造函数
- 拿构造函数举例,虽然声明了模板构造,但是并不会替代原来的构造函数
7.关于.template的使用 这个可以直接调用模板成员函数
MEMBER::Member m;
m.template func<int>(5);
8.模板变量 示例:
template<typename T>
constexpr T val{ 3.1415926 };//默认初始化的值
template<typename T>
T Value;
9.模板变量对于数据成员
template<typename T>
class A {
public:
static constexpr int a = 50;
};
template<typename T>
int val = A<T>::a;
10.模板模板参数
template<typename T, template<typename A, typename B = std::allocator<A>>class Cont = std::vector>class MVector {
public:
Cont<T> cont;
template<typename T1,template<typename A,typename B = std::allocator<A>>class Cont1>
MVector<T, Cont>& operator=(MVector<T1, Cont1>& t) {
}
template<typename ,template<typename,typename>class>
friend class MVector;
};