今天我们来聊聊 decltype
关键字,它是 C++11 新增的一个关键字,和 auto
的功能一样,都是用来在编译时期进行自动类型推导。
decltype
是「declare type」的缩写,译为「声明类型」。
既然已经有了 auto
关键字,为什么还需要 decltype
?
因为 auto
并不适用于所有的自动类型推导场景,在某些特殊情况下 auto
用起来非常不方便,甚至压根无法使用,所以引入了 decltype
关键字。
下面通过介绍 decltype
的用法,体会一下和 auto
的不同。
decltype
的用法
decltype
关键字用于检查实体的声明类型或表达式的类型,并且不会对表达式进行求值。
1、基本用法
decltype
可以直接用于变量,获取其类型。
cpp
int x = 1;
decltype(x) y = x; // y 的类型为 int
decltype(10.8) z = 5.5; //z 的类型为 double
decltype(z + 100) a; //a 的类型为 double
2、与复杂表达式一起使用
decltype
可以用于更复杂的表达式中。
cpp
std::vector<int> v;
decltype(v.begin()) it = v.begin(); // it的类型为std::vector<int>::iterator
3、用于函数返回类型推导
在 C++11 及以后的版本中,decltype
可用于精确推导函数返回类型,尤其是当返回类型依赖于函数参数时。
cpp
template<typename A, typename B>
auto add(A a, B b) -> decltype(a + b) {
return a + b;
}
在这个例子中,函数 add
的返回类型通过 decltype
自动推导,这样函数就能够处理不同类型的参数,并返回正确的类型。
4、结合auto
和decltype
用于自动类型推导
decltype
还可以与auto
结合使用,以便在需要类型匹配的场景中自动推导变量类型。
cpp
auto x = 1;
decltype(auto) y = x; // y的类型为int
decltype 推导规则
上面的例子让我们初步感受了 decltype
的用法,但你不要认为 decltype
就这么简单,它的用法实际上可以非常复杂。
如果 decltype(exp)
中的表达式 exp
,其类型为 T
,那么:
-
如果 exp 的值类型是 xvalue(将亡值),decltype 推导出的类型是 T&&;
-
如果 exp 的值类型是 lvalue(左值),decltype 推导出的类型是 T&;
-
如果 exp 的值类型是 prvalue(纯右值),decltype 推导出的类型是 T。
上面这三条规则有点抽象,不像人说的话,其中的「值类型」,在后面的文章中会详细解释。
当前只要记住下面这三条规则,就能应对 90% 的场景:
-
如果
exp
是一个不被括号()
包围的表达式,或者是一个类成员访问表达式,或者是一个单独的变量,那么decltype(exp)
的类型就和exp
一致,这是最常见的情况。 -
如果
exp
是函数调用,那么decltype(exp)
的类型就和函数返回值的类型一致。 -
如果
exp
是一个左值,或者被括号()
包围,那么decltype(exp)
的类型就是exp
的引用;假设exp
的类型为T
,那么decltype(exp)
的类型就是T&
。
代码示例
我们通过一个具体的例子来展示 decltype
的实际应用。
假设我们需要实现一个泛型函数,该函数能够根据传入参数的类型动态决定返回值的类型。
cpp
#include <iostream>
#include <vector>
template<typename T>
auto multiply(T x, T y) -> decltype(x * y) {
return x * y;
}
int main() {
auto result1 = multiply(5, 4); // result1的类型为int
std::cout << "int result: " << result1 << std::endl;
auto result2 = multiply(3.14, 2.71); // result2的类型为double
std::cout << "double result: " << result2 << std::endl;
}
在这个例子中,函数 multiply
能够根据传入参数的类型(无论是整型还是浮点型),通过 decltype
自动推导出正确的返回类型。这种类型推导不仅使代码更加灵活和通用,也保持了类型安全,避免了类型不匹配的错误。
decltype
提供了一种方式,来捕获表达式的类型,而不实际计算表达式的值。这在模板编程、泛型编程以及需要精确控制类型的场景中非常有用。结合 auto
关键字,decltype
为C++程序提供了更大的灵活性和表达能力。