decltype用于编译期推导表达式形式类型,保留引用和cv限定符;变量名推导声明类型,(x)视为左值推导T&,函数调用推导结果类型;常用于返回类型后置、模板编程及declval类型探测。

decltype 用来在编译期推导表达式的类型,不求值、不执行,只看表达式“长什么样”,就决定它是什么类型。
推导表达式本身的类型(不是结果值的类型)
和 auto 不同,decltype 关注的是表达式在代码中出现的形式:
- 变量名:推导为该变量的声明类型(带引用、const 等限定符);
- 加括号的变量名,如 (x):视为表达式,若 x 是左值,则 decltype(x) 是 T&;
- 函数调用、算术表达式等:推导其返回/计算结果的类型(按值返回则通常不带引用)。
常用于模板和泛型编程中保持原类型精度
比如写一个通用的 wrapper 函数,想让返回类型和某个表达式完全一致(包括 const、引用),auto 可能会退化掉引用,而 decltype 能保留:
-
decltype(func(a, b)) result = func(a, b);—— result 类型和 func 调用结果一模一样; - 配合 declval 在未定义对象时做类型探测,常见于 SFINAE 和概念约束中。
和 auto 的关键区别:是否保留引用和 cv 限定符
假设 const int& x = 42;:
立即学习“C++免费学习笔记(深入)”;
-
auto y = x;→ y 是const int(引用被丢弃); -
decltype(x) y = x;→ y 是const int&(原封不动); -
decltype((x)) y = x;→ 因为 (x) 是左值表达式,y 是const int&。
实际用得最多的地方:返回类型后置语法
当函数返回类型依赖参数表达式时,必须用 decltype(配合 decltype(auto) 更简洁):
templateauto add(T&& t, U&& u) -> decltype(t + u) { return t + u; } - C++14 起可直接写
decltype(auto) add(...) { return t + u; },自动推导返回类型并保留引用等属性。
基本上就这些。它不复杂,但容易忽略括号带来的语义变化 —— 多写两个括号,类型可能就从 T 变成 T&。









