文章

C++ decltype自动类型推导

C++ decltype自动类型推导

decltype是C++引入的一个关键字,用来在编译期推导表达式的类型,而不实际求值。

常用于模板编程、泛型代码中,用来获取变量或表达式的精确类型

基本语法

1
decltype(表达式)

作用:返回表达式的类型,仅查询,并不会对表达式进行求值

基本示例

1
2
int x = 10;
decltype(x) y = 20;	// y的类型是int

等价于

1
int y = 20;
  • using/typedef结合,用于定义类型
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
using size_t = decltype(sizeof(0));	// sizeof(0)的返回值为size_t类型

using ptrdiff_t = decltype((int*)0 - (int*)0);	// 指针相减的结果是ptrdiff_t,有符号整数类型

using nullptr_t = decltype(nullptr);	// nullptr的类型是std::nullptr_t

vector<int> vec;
typedef decltype(vec.begin()) vectype;	
// vec.begin()是一个迭代器类型
// 等效于 typedef std::vector<int>::iterator vectype;
for (vectype i = vec.begin(); i != vec.end(); i++) {
	// ...
}

## decltype的核心规则

| 表达式                      | 推导结果     | 说明                     |
| :----------------------- | :------- | :--------------------- |
| `decltype(x)`            | `T`      | 如果 `x` 是一个变量名,则结果是它的类型 |
| `decltype((x))`          | `T&`     | 注意多了一层括号,结果是左值引用类型     |
| `decltype(std::move(x))` | `T&&`    | 如果表达式是右值,则返回右值引用类型     |
| `decltype(10)`           | `int`    | 字面量的类型                 |
| `decltype(x + y)`        | 表达式的结果类型 | 取决于运算符重载和操作数类型         |

代码:

```c++
int a = 0;
int& b = a;

decltype(a) c = a;	// c的类型是int
decltype(b) d = a;	// d的类型是int&

decltype((a)) e = a;	// e的类型是int&
  • decltype(x):变量的类型本身
  • decltype((x)):始终是左值引用类型

在模板中的应用

在泛型编程中,decltype通常配合autodecltype(auto)来使用,用来声明返回值的类型

1
2
3
4
template <typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
    return a + b;
}

C++14后可以简写:

1
2
3
4
template <typename T, typename U>
auto add(T a, U b) {
    return a + b;  // 编译器自动推导返回类型
}

decltpye和auto的区别

特性autodecltype
依据初始化表达式的值类别表达式的类型本身
是否求值✅ 求值❌ 不求值
常用于推导变量类型获取表达式的类型
括号影响不影响有显著影响
1
2
3
4
5
int a = 0;
int& b = a;

auto x = (b);       // x 是 int
decltype((b)) y = a; // y 是 int&
  • 高级用法:decltype(auto)
1
2
3
4
5
int x = 42;
int& f() { return x; }

auto a = f();        // a 是 int
decltype(auto) b = f(); // b 是 int&

总结

用法含义
decltype(expr)获取 expr 的类型(不求值)
decltype(auto)自动推导类型并保持引用/值性质
(x) vs x多一层括号时会返回引用类型
应用场景模板推导、泛型函数返回值声明、类型萃取
本文由作者按照 CC BY 4.0 进行授权