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 进行授权
