C++ 中 auto 和 decltype 的用法 (update 20241106)
1. auto 占位符
1.1 规则
auto
推导的原则为:保持原有变量的类型(如cv
限定),大致分两种情况:
auto
:auto
含义是创建了一个新的变量
:- 表达式为
T
或者T&
或者const T&
–auto
推导为T
– 即新变量的类型去除cv
限定 (如果原有表达式有cv
限定); - 表达式为
T* const
或者T*
–auto
推导为T*
– 新变量去除cv
限定; - 表达式为
const T*
或者const T* const
–auto
推导为const T*
,即保持指针指向的内存区域的const
属性。
- 表达式为
auto&
:auto&
含义是alias
,故auto&
推导的结果是原有类型的的引用,不能少任何一个限定符,如:const T* const
推导为const T* const &
;const T
推导为const T&
;
1.2 一些应用场景
- 范围循环
1
2
3
4
std::vector<int> numbers = {1, 2, 3, 4, 5};
for (const auto& num : numbers) {
std::cout << num << std::endl; // num 的类型被推导为 const int&
}
- lambda 表达式
1
2
3
auto add_func = [](int a, int b) -> int {
return a + b;
};
- 结构化绑定(
c++17
新特性)
1
2
std::pair<int, double> myPair = std::make_pair(42, 3.14);
auto [first, second] = myPair; // 结构化绑定,first 和 second 的类型被推导为 int 和 double
- 返回类型后置
1
2
3
4
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}
2. decltype
decltype
类型推导规则:
2.1 decltype(entity)
如果 entity
是一个不被括号包围的标识符、类访问表达式,那么decltype(entity)
与 entity
类型一致。
2.2 decltype((expression))
如果expression
是一个表达式,计算结果为类型T
,那么:
- 如果
expression
为xvalue(将亡值)
,那么decltype
的结果是T&&
。 - 如果
expression
为lvalue
,那么decltype
的结果是T&
。 - 如果
expression
为prvalue(纯右值)
,那么decltype
的结果是T
。
2.3 说明及示例
注意第一点中强调了 entity
是一个不被括号包围的标识符。因为当一个标识符被括号包围时,它就是一个左值表达式了,对应上面第二大点的第二小点。比如说 int x = 0;
,x
是一个标识符,所以 decltype(x)
的结果为 int
。但是 (x)
就是一个左值表达式,decltype((x))
的结果就是 int&
。
3. 参考
本文由作者按照 CC BY 4.0 进行授权