C++泛编程
C++泛编程
1.auto
auto的主要用途:让编译器自动推断变量的类型
- 代替冗长复杂的变量声明(函数指针)
- 在模板中,用于声明依赖模板参数的变量
- 函数模板依赖模板参数的返回值
- 用于Lambda表达式中
2.函数模板
1 | template <typename T> |
注1:可以为类的成员函数创建模板,但不能是虚函数和析构函数。
注2:使用函数模板时,如果自动类型推导,不会发生隐式类型转换,而如果显式指定了函数模板的数据类型,则可以发生隐式类型转换。
编译器使用各种函数的规则:
普通函数>具体化>常规模板
如果希望使用函数模板,可以用空模板参数强制使用函数模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 普通函数
void show(int a) {
std::cout << "普通函数: " << a << std::endl;
}
// 函数模板
template<typename T>
void show(T a) {
std::cout << "函数模板: " << a << std::endl;
}
int main() {
int value = 42;
// 默认情况下,编译器可能优先选择普通函数
show(value); // 输出: 普通函数: 42
// 强制使用函数模板
show<>(value); // 输出: 函数模板: 42
return 0;
}如果函数模板能产生更好的匹配,将优先于普通函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 普通函数
void display(long a) {
std::cout << "普通函数: " << a << std::endl;
}
// 函数模板
template<typename T>
void display(T a) {
std::cout << "函数模板: " << a << std::endl;
}
int main() {
int value = 10;
// 尽管有一个接受long类型的普通函数,
// 但函数模板提供了对int类型更直接的匹配。
display(value); // 输出: 函数模板: 10
return 0;
}
函数模板分文件编写:
- 函数模板只是函数的描述,没有实体,创建函数模板的代码放在头文件中
- 函数模板具体化有实体,编译原理和普通函数一样,声明放在头文件中,定义放在源文件中。
3.类模板(泛化、全特化、偏特化)
模板泛化
模板泛化是不关心具体的类型,而是提供了通用的实现。
1 | // 泛化的类模板 |
全特化
全特化:为某些类型提供更高效的实现
成员函数的全特化
1 | // 成员函数的特化 |
类模板全特化:
1 | // 模板的特化 |
偏特化
模板偏特化是指在泛化的模板基础上,对其中的某一部分进行特化。
模板参数数量的偏特化:特化部分参数,还存在一部分参数使用通用的模板定义。
1 | // 泛化的类模板,有两个模板参数 |
模板参数范围的偏特化:对模板的参数范围进行缩小
- const 特化:
1 | // 泛化的类模板 |
- 指针特化:
1 | // 泛化的类模板 |
- 左值引用特化:
1 | // 泛化的类模板 |
- 右值引用特化:
1 | // 泛化的类模板 |
注:函数模板是不能偏特化的,只有类模板可以进行偏特化。函数模板可以不显式指定类型。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 丹青两幻!
评论