decltype
能够获取一个表达式的类型. 而auto
关键字是在赋值时获取变量的类型. decltype
的一般用法: int a = 0; decltype(i) b = 0;
.
decltype
的用途:
- 定义新类型:
using nullptr_t = decltype(nullptr);
- 获取匿名类型:
struct {
int m_a;
} num = {.m_a = 0,};
decltype(num) b;
- 在泛型编程中与
auto
关键字结合, 实现类型自动推倒:
#include <iostream>
template <typename T, typename U>
auto add(T x, U y)->decltype(x + y) {
return x + y;
}
int main() {
std::cout << add(1, 2.3) << std::endl; // 输出: 3.3
}
decltype
类型推导规则:
- 不适用于重载函数.
- 实体类型: 没有带括号的标记符表达式或类成员访问表达式.
int i = 0;
decltype(i) a = 0; // int
int arr[2] = {0};
decltype(arr) a = {0, 1}; // int(a)[2] = {0, 1};
int *ptr = nullptr;
decltype(ptr) a = nullptr; // int*
struct num {int m_a;}n;
decltype(n.m_a) a = 0; // int
- 实体类型&&: 将亡值.
int&& right_value_reference(){};
decltype(right_value_reference()) a = 1; // int&&
- 实体类型&: 左值.
int i = 0;
int *ptr = nullptr;
decltype((i)) a = 0; // int&
decltype (++i) a = 0; //int& ++i返回i的左值
decltype(arr[5]) a = 0;//int& []操作返回左值
decltype(*ptr) a = 0;//int& *操作返回左值
decltype("hello") a = "world"; // 符串字面常量为const左值
- 实体类型: 上述情况都不是.
int i = 0;
decltype(1) a = 0; //const int
decltype(Func(1)) a = true;//const bool
decltype(i++) a = 0; //int i++返回右值
注意:
- 非字符串字面量常量为
右值
, 使用最后一条规则. - 可通过
std::is_lvalue_reference<decltype(++i)>::value
和std::is_rvalue_reference<decltype(++i)>::value
判断一个表达是左值
还是右值
. 例子:
#include <iostream>
#include <type_traits>
int main() {
int i = 0;
std::cout << std::is_lvalue_reference<decltype(++i)>::value << std::endl; // 输出: 1
std::cout << std::is_rvalue_reference<decltype(++i)>::value << std::endl; // 输出: 0
}
如果觉得有帮助,可以扫描右边的微信打赏码支持一下.