[C++]现代C++语言核心特性解析 Chapter 4
decltype说明符(C++11~C++17)
1 使用decltype说明符
decltype说明符可以获取对象或者表达式的类型。并且可以用于非静态成员变量。
用处
在c++11标准中,不支持对auto声明的返回类型进行推导,所以需要用decltype在函数的尾部对返回类型进行说明
1
2
3
4
5
6
7template<class T1, class T2>
auto sum(T1 a1, T2 a2)->decltype(a1 + a2)
{
return a1 + a2;
}
auto x4 = sum(5, 10.5);在c++14标准中,支持对auto声明的返回类型进行推导,可以简化为
1
2
3
4
5
6
7template<class T1, class T2>
auto sum(T1 a1, T2 a2)
{
return a1 + a2;
}
auto x5 = sum(5, 10.5);但是,上述代码有一点问题,如果我们期望返回一个引用,上述代码无法做到。配合decltype可以做到
1
2
3
4
5
6
7
8
9
10template<class T>
auto return_ref(T& t)->decltype(t)
{
return t;
}
int x1 = 0;
static_assert(
std::is_reference_v<decltype(return_ref(x1))> // 编译成功
);
2 推导规则
decltype(e)(其中e的类型为T)的推导规则有5条。
- 如果e是一个未加括号的标识符表达式(结构化绑定除外)或者未加括号的类成员访问,则decltype(e)推断出的类型是e的类型T。如果并不存在这样的类型,或者e是一组重载函数,则无法进行推导。
- 如果e是一个函数调用或者仿函数调用,那么decltype(e)推断出的类型是其返回值的类型。
- 如果e是一个类型为T的左值,则decltype(e)是T&。
- 如果e是一个类型为T的将亡值,则decltype(e)是T&&。
- 除去以上情况,则decltype(e)是T。
3 cv限定符的推导
- 通常情况下,推导会同步e的cv限定符。
- 当e是未加括号的成员变量时,父对象表达式的cv限定符会被忽略
- 当e是加括号的成员变量时,父对象表达式的cv限定符会同步到结果
4 decltype(auto)
C++14标准中出现了decltype和auto两个关键字的结合体:decltype(auto)。它的作用简单来说,就是告诉编译器用decltype的推导表达式规则来推导auto。另外需要注意的是,decltype(auto)必须单独声明,也就是它不能结合指针、引用以及cv限定符。
有了这个用法,上述返回引用的类型可以进一步优化
1 |
|
5 decltype(auto)作为非类型模板形参占位符
与auto一样,在C++17标准中decltype(auto)也能作为非类型模板形参的占位符
[C++]现代C++语言核心特性解析 Chapter 4
https://erlsrnby04.github.io/2024/10/20/C-现代C-语言核心特性解析-Chapter-4/