decltype是C++11用于编译期推导表达式声明类型的关键词,忠实保留引用、const/volatile,括号可改变值类别;与auto不同,它不忽略顶层cv限定符且无需初始化。
decltype 是 C++11 引入的关键字,用于在编译期**推导表达式的类型**,不求值、不执行,只看表达式的形式和上下文。它和 auto 都是类型推导工具,但逻辑不同:auto 看变量初始化的“结果类型”,decltype 看表达式本身的“声明类型”。
decltype(e) 的结果类型由表达式 e 的形式决定:
例子:
int x = 42; const int& y = x; decltype(x) a; // int decltype(y) b; // const int& decltype(x + y) c; // int(x+y 是纯右值,结果是 int) decltype((x)) d; // int&(加括号后是左值表达式)
在泛型编程中,尤其配合 std::forward 和完美转发时,decltype 能保留参数的原始引用性,避免类型退化。
例如:
templateauto call(F&& f, Args&&... args) -> decltype(std::forward (f)(std::forward(args)...)) { return std::forward (f)(std::forward(args)...); } // 返回类型由调用表达式实际推导,支持任意可调用对象
两者都做类型推导,但出发点不同:
latile对比:
int i = 42; const int& ri = i; auto a1 = i; // int(丢掉引用和 const) auto a2 = ri; // int(同上) auto& a3 = i; // int&(显式加 & 才保留引用) decltype(i) d1; // int decltype(ri) d2; // const int& decltype((i)) d3; // int&(括号使 i 成为左值表达式)
decltype 是 SFINAE 和类型特征(type traits)的重要支撑:
小技巧:decltype(0) 是 int,decltype(nullptr) 是 std::nullptr_t,这些可作为类型占位符使用。
基本上就这些。decltype 不复杂,但容易忽略括号带来的左值/右值语义变化——记住:带括号的表达式通常是左值,这对引用推导至关重要。