一、模板参数的推断
我们在实例化一个类模板的时候,有两种方法:
一种是使用
<
T
>
<T>
<T>来显式推断生成相应的类
另一种是不使用
<
T
>
<T>
<T>来隐式推断生成相应的类
具体如下:
template<typename T>
struct A {
T val1, val2;
A(T val1_, T val2_) : {}
};
void Test() {
A(1, 1); //隐式推断
A<int>(1, 1); //显式推断
}
其中,两种推断方案都基于构造函数,如果我们删除了构造函数,那么我们就无法生成相应的类。
二、模板参数的推断指南
1.隐式推断
模板的推断指南(deduction guide),是C++17引入的概念。
推断指南主要是用来在推断模板参数时提供推断指引。
通常情况下,编译器自带一个推断指南,形式上如:
//隐式推断
template<typename T>
A(T, T) -> A<T>;
所以,即使我们只要有构造函数,也可以不写这个推断指南,也能生成相应的类。
对于这个类
template<typename T>
struct B {
T val1, val2;
B(T val1_, T val2_) : {}
};
如果我们调用
void Test2() {
B(1, 1); //调用隐式推断,推断为B<int>
}
那么将会实例化一个 i n t int int类型的 B B B类,因为此时调用的是默认的推断指南
2.自定义推断
但如果我们想要让其推断为
d
o
u
b
l
e
double
double类型呢?
此时需要自定义一个推断指南,如下:
//显式推断
template<typename T>
B(T, T) -> B<double>;
void Test2() {
B(1, 1); //显示调用自定义推断,推断为B<double>
}
此时生成的就是 d o u b l e double double类的 B B B类啦
3.无构造函数实例化
前面两种实例化模板的方式都是通过构造函数来实例化模板。
在
C
+
+
C++
C++中,我们还可以通过初始化列表+推断指南的方式来实例化模板
具体代码如下:
template<typename T>
struct MyType {
T val1, val2;
//不存在构造函数
};
//显式推断
template<typename T>
MyType(T,T) -> MyType<T>;
//使用初始化列表
void Test3() {
//使用初始化列表相当于使用了构造函数
MyType t1{ 1,1 };
MyType<double>t2{2, 3};
}
我们通过 d u m p b i n dumpbin dumpbin来验证一下
确实实例化出了这个类型。
当然,使用这种方法有局限性,需要满足以下条件: