C++ 的 auto 与 decltype
2025-04-01
auto 会去除 &、const 和 volatile 修饰符
1 | int a = 40; |
decltype 实用场景
decltype(auto) 完美类型推断
decltype(auto)
能顺利解决上面的问题,它会保留变量的所有属性。
1 | int a = 40; |
在泛型代码中进行返回值类型转发
另一个场景是,在泛型代码中,我们希望能够完美转发一个返回值类型,而事先并不知道处理的是一个引用还是一个值。decltype(auto)
赋予了你这种能力:
1 | template<class Fun, class... Args> |
decltype(auto)
会像 decltype
那样推导
fun(...)
表达式的类型,并保留其值类别(左值/右值)和
const/volatile
限定符,从而实现返回类型的完美转发。
在递归模板中延迟返回值类型推导
当模板的返回类型被指定为
decltype(iter(Int<i-1>{}))
而不是
decltype(auto)
时,遇到了模板实例化过程中的无限递归问题。
原始(有问题)代码可能类似:
1 | template<int i> |
使用 decltype(auto)
的修正后代码:
1 | template<int i> |
这里使用 decltype(auto)
是为了延迟返回类型的推导,直到模板实例化过程递归结束后,根据函数体内的
return
语句来确定实际的返回类型,从而避免了在确定函数签名时就进行递归推导导致的无限循环。