模板编写之,一般化 偏特化 全特化

对于模板编写而言, 这个问题可能会让新手迷糊, 下面我来帮各位总结一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//一般化的模板
template<typename T> //声明一个类型T
class A {
T a;//使用先前声明的类型
};

//错误的一般化的模板 示例1
template<typename vector<T>> //报错:找不到T的定义
//原因 typename后面需要接收一个不完全的类型, 不能接收一个偏特化(半完全)的类型
class A {
T a;//使用先前声明的类型
};

//错误的一般化的模板 示例2
template<typename vector<int>> //报错:非类型模板参数不能为类类型
//原因 typename后面需要接收一个不完全的类型, 不能接收一个完全的类型
//接收完成后, 相当于为下文的代码声明了一个类型T
class A {
T a;//使用先前声明的类型
};


//偏特化的模板
//偏特化不能用于模板函数,只能用于模板类
template<typename T> //声明一个类型T
class A<vector<T>> {//当实际接收的类型满足一定的样式时, 会调用这个偏特化类的构造函数
//这个样式不能是完全补足的
T a;//使用先前声明的类型
};

//错误的偏特化的模板 示例1
//偏特化不能用于模板函数,只能用于模板类
template<typename T> //声明一个类型T
class A<vector<int>> {//完全补足了类型
//报错: 部分专用化(也就是偏特化)无效, 该类型已完全专用化(也就是全特化)
T a;//使用先前声明的类型
};


//全特化的模板
template<> //既然是全特化, 不需要声明任何不完全的类型
class A<vector<int>> {//实际接收的类型需要写成一个完全类型, 不能写不完全类型
T a;//使用先前声明的类型
};

//错误全特化的模板 示例1
template<> //既然是全特化, 不需要声明任何不完全的类型
class A<vector<T>> {//实际接收的类型需要写成一个完全类型, 不能写不完全类型
// 前面没有用typename T声明过T, 而T也不是一个完全类型的话, 那么就会报错, 找不到T的定义
T a;//使用先前声明的类型
};

//错误全特化的模板 示例2
template<typename T> //既然是全特化, 不需要声明任何不完全的类型
class A<vector<T>> {//实际接收的类型需要写成一个完全类型, 不能写不完全类型
//因此这个是偏特化 而不是全特化
T a;//使用先前声明的类型
};

简单来说就是, 一般化和偏特化都有不完全类型的存在 因此在第一行需要用typename声明一些需要用到的不完全类型template<typename T>

然后在第二行决定是否需要写明部分专用化的不完全类型<vector<T>>

一般化模板不需要写明(放空 ), 函数模板不允许写明(非法), 偏特化模板必须写明<vector<T>>, 而且不允许写死为完全类型<vector<int>>

如果是全特化, 就不存在不完全类型, 那么第一行就什么都不需要声明template<> , 第二行需要写死接收的完全类型<vector<int>>

另外就是, 全特化和偏特化都是基于一般化模板的, 如果没有声明一般化模板, 是不能声明后两者的, 后两者和一般化的关系是后者把一些内容填充到前者, 然后通过参数类型查找, 找到最适合的特化类型

也就是说, 声明一个偏特化或者全特化的模板时, 如果特化的部分与一般化的对应部分对照不上,则会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//一般化版本
template<typename T>//只声明了一个不完全类型
void swap(T&,T&){//接收的类型需要和参数类型一致
}


template<>
void swap<int>(char&,char&){//接收的类型需要和参数类型一致
}

template<>
void swap<int,int>(int& a,int& b){
//只声明了一个不完全类型, 但这里要求尖括号内需要接收两个完全类型
}
image-20230618155233036
image-20230618155258347
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2019-2024 kier Val
  • Visitors: | Views: