decltype类型推导
decltype
decltype(expression) //获取表达式的类型--在编译期计算
decltype在技术和使用上和sizeof非常像,都需要编译器在编译期计算类型,但是sizeof返回的是整数,而decltype得到的是类型。
decltype和auto的异同:
-
与auto不同点:
decltypr的类型推导并不是像auto一样是从变量声明的初始化表达式获得变量的类型,decltype总是以一个普通的表达式为参数,返回该表达式的类型。
-
与auto相同点:
作为一个类型指示符,decltype可以将获得的类型来定义另外一个变量;
declttype类型推导也是在编译时进行的
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
int a;
decltype(a) b = 0;
cout<<"a的类型是"<<typeid(a).name()<<endl;
cout<<"b的类型是"<<typeid(b).name()<<endl;
float c;
double d;
decltype(c + d ) e;
cout<<"e的类型是"<<typeid(e).name()<<endl;
return 0;
}
输出:
a的类型是i //i代表int
b的类型是i
e的类型是d //ddouble
可以看到变量b的类型由decltype(a)进行声明,表示b跟a这个表达式返回的类型相同;而e的类型则由(c +
d)这个表达式返回的类型相同,c + d的表达式的类型为double,所有e的类型被decltype推导为double。
decltype的应用
decltype推导规则
表达式为普通变量或者普通表达式或者类表达式,在这种情况下,使用 decltype 推导出的类型和表达式的类型是一致的。
#include <iostream>
#include <string>
using namespace std;
class Test
{
public:
string text;
static const int value = 110;
};
int main()
{
int x = 99;
const int &y = x;
decltype(x) a = x;
decltype(y) b = x;
decltype(Test::value) c = 0;
Test t;
decltype(t.text) d = "hello, world";
return 0;
}
变量 a 被推导为 int 类型 变量 b 被推导为 const int & 类型 变量 c 被推导为 const int 类型 变量 d
被推导为 string 类型
表达式是函数调用,使用 decltype 推导出的类型和函数返回值一致。
class Test{...};
//函数声明
int func_int(); // 返回值为 int
int& func_int_r(); // 返回值为 int&
int&& func_int_rr(); // 返回值为 int&&
const int func_cint(); // 返回值为 const int
const int& func_cint_r(); // 返回值为 const int&
const int&& func_cint_rr(); // 返回值为 const int&&
const Test func_ctest(); // 返回值为 const Test
//decltype类型推导
int n = 100;
decltype(func_int()) a = 0;
decltype(func_int_r()) b = n;
decltype(func_int_rr()) c = 0;
decltype(func_cint()) d = 0;
decltype(func_cint_r()) e = n;
decltype(func_cint_rr()) f = 0;
decltype(func_ctest()) g = Test();
变量 a 被推导为 int 类型
变量 b 被推导为 int& 类型
变量 c 被推导为 int&& 类型
变量 d 被推导为 int 类型
变量 e 被推导为 const int & 类型
变量 f 被推导为 const int && 类型
变量 g 被推导为 const Test 类型
函数 func_cint () 返回的是一个纯右值(在表达式执行结束后不再存在的数据,也就是临时性的数据),对于纯右值而言,只有类类型可以携带const、volatile限定符,除此之外需要忽略掉这两个限定符,因此推导出的变量 d 的类型为 int 而不是 const int。
表达式是一个左值,或者被括号 ( ) 包围,使用 decltype 推导出的是表达式类型的引用(如果有 const、volatile 限定符不能忽略)。
#include <iostream>
#include <vector>
using namespace std;
class Test
{
public:
int num;
};
int main() {
const Test obj;
//带有括号的表达式
decltype(obj.num) a = 0;
decltype((obj.num)) b = a;
//加法表达式
int n = 0, m = 0;
decltype(n + m) c = 0;
decltype(n = n + m) d = n;
return 0;
}
obj.num 为类的成员访问表达式,符合场景 1,因此 a 的类型为 int obj.num 带有括号,符合场景 3,因此 b 的类型为
const int&。 n+m 得到一个右值,符合场景 1,因此 c 的类型为 int n=n+m 得到一个左值 n,符合场景 3,因此 d
的类型为 int&