C++17 类模板参数推导

C++17 类模板参数推导

C++17引入了类模板参数推导 (Class Template Argument Deduction, CTAD),使得编译器能够在实例化模板类时自动推导出模板参数类型。结合构造函数模板推导,这意味着当你在构造一个类模板的对象时,可以省略模板参数,编译器会根据构造函数的参数自动推导出模板参数。

基本使用

假设你有一个简单的模板类 Pair,它用于存储两个值:

1
2
3
4
5
6
7
template <typename T1, typename T2>
struct Pair {
T1 first;
T2 second;

Pair(T1 a, T2 b) : first(a), second(b) {}
};

C++17 之前,你必须显式地指定模板参数:

1
Pair<int, double> p(1, 3.14);

但在 C++17 中,你可以省略模板参数:

1
Pair p(1, 3.14); // 编译器会自动推导出 Pair<int, double>

编译器通过构造函数的参数类型自动推导出 T1 和 T2 的类型,因此无需显式指定模板参数。

推导指南

有时,编译器可能无法从构造函数的参数推导出所需的模板参数类型。在这种情况下,你可以提供一个推导指南 (Deduction Guide) 来帮助编译器推导模板参数。

1
2
3
4
5
6
7
8
9
10
template <typename T1, typename T2>
struct Pair {
T1 first;
T2 second;

Pair(T1 a, T2 b) : first(a), second(b) {}

// 另外一种构造函数
Pair(T1 a) : first(a), second() {}
};

在这里,如果你只传递一个参数,编译器可能无法正确推导 T2 的类型。你可以为此提供一个推导指南

1
2
template <typename T1>
Pair(T1) -> Pair<T1, T1>;

这个推导指南告诉编译器,当你构造一个 Pair 对象并且只传递一个参数时,模板参数 T2 应该与 T1 相同。

总结

C++17 的构造函数模板推导大大简化了模板类的使用,减少了重复代码的需求,并提高了代码的可读性。推导指南提供了进一步的灵活性,允许你自定义模板参数的推导方式。