auto故名意义自动推导,没什么太特别的,可以自行了解一下c++的auto关键字是什么
decltype 如果不了解的,可以看这篇文章:c++的decltype是什么
如果没有深入了解,会感觉两者好像作用是很类似的,其实auto 和 decltype 虽然都做“类型推导”,但目标和规则不同,不能互相替代。
1. auto 是定义变量时的类型推导
auto 主要用于:
int main() {
auto x = 1;
return 0;
}
它的推导规则接近模板按值传参,会丢弃引用和顶层 const,数组/函数可能退化为指针:
int n = 0;
int& r = n;
const int c = 1;
auto a = r; // a 是 int,不是 int&
auto b = c; // b 是 int,const 丢了
所以 auto 适合“我要一个变量,值拷贝出来,类型你帮我推”。
这里有一个概念:顶层const和底层const
可见这篇文件:什么是顶层 const什么是底层const
2. decltype 是查询表达式的精确类型
decltype(expr) 不定义变量,也不需要初始化,更不会求值:
decltype(r) d = n; // d 是 int&
decltype(c) e = c; // e 是 const int
decltype((n)) f = n; // f 是 int&,因为 (n) 是左值表达式
它保留引用和 cv 限定,规则大致是:
-
decltype(变量名):得到变量声明时的类型;
-
decltype(左值表达式):通常得到 T&;
-
decltype(右值表达式):得到 T。
3. 关键区别
int n = 0;
int& r = n;
auto x = r; // int
decltype(r) y = n; // int&
auto 更像“复制一个值出来”,decltype 更像“问编译器:这个表达式到底是什么类型”。
4. decltype 的典型用途
尾置返回类型 / 表达式返回类型
template <class T, class U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}
这里返回类型依赖参数表达式 t + u,auto 单独做不到。
模板元编程、SFINAE、类型计算
decltype(std::declval<T>().foo())
用于获取某个表达式的结果类型。
保留引用返回
template <class Container>
auto front(Container& c) -> decltype(c.front()) {
return c.front();
}
如果 front() 返回引用,返回类型也保留引用。
C++14 的 decltype(auto)
decltype(auto) f() {
int x = 0;
return (x); // 返回 int&
}
auto 会返回值,decltype(auto) 可以保留引用。
一句话总结
-
auto:定义变量时,按值推导一个方便的类型,会丢引用/顶层 const。
-
decltype:查询表达式的精确类型,保留引用和 cv,不求值。
-
二者是互补关系:auto 负责“声明变量”,decltype 负责“类型计算/精确获取类型”。
所以不是有了 auto 就不需要 decltype,而是很多场景 auto 根本表达不了,例如保留引用、尾置返回类型、模板中推导表达式类型等。



