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 }