欢迎光临
我们一直在努力

c++ 有了auto为什么还搞一个decltype

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 根本表达不了,例如保留引用、尾置返回类型、模板中推导表达式类型等。

赞(0)
未经允许不得转载:171主机测评 » c++ 有了auto为什么还搞一个decltype
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址