Modern C++(三)decltype关键字

C++11中新添加了decltype关键字,它用于在编译时推导表达式的类型。因为decltype在编译期推导类型,并不会计算表达式的值。
我们看一下它是如何使用的

//注释为变量类型
int a = 5;
decltype(a) b = 5;			//int
decltype(a + b) c = 5;		//int

const int& d = a;
decltype(d) e = 5;			//const int&

const int* f = new int(5);
decltype(f) g = &a;			//const int*

decltype(a)* h = &a;		//int*
const decltype(a)* i = &a;	//const int*

decltype(h)* j = &h;		//int**
decltype(i)* k = &i;		//const int**

decltype推导有以下规则decltype(e)

  1. 当e为标识符表达式、类访问表达式,则推导的类型为e的具体类型

  2. 若e为函数调用,则推导出的类型为函数调用的返回值类型

  1. 若e的类型为左值,则推导出的是e的左值引用,否则为e原始类型

推导规则1

int a = 5;
decltype(a) b = a;					//int

const int& c = a;
decltype(c) d = a;					//const int&

struct DeclTypeTest
{
	int a;
	static const int b = 5;
};

DeclTypeTest test;
decltype(test.a) e = 5;				//int

decltype(DeclTypeTest::b) f = 5;	//const int

根据推导规则1,b、d、e、f都保留了表达式的原属性

推导规则2

int funcr();				//纯右值
int& funcl();				//左值
int&& funcx();				//x值

const int cfuncr();			//纯右值
const int& cfuncl();		//左值
const int&& cfuncx();		//x值

int a = 5;

decltype(funcr()) b = 5;	//int
decltype(funcl()) c = a;	//int&
decltype(funcx()) d = 5;	//int&&

decltype(cfuncr()) e = 5;	//int
decltype(cfuncl()) f = a;	//const int&
decltype(cfuncx()) g = 5;	//const int&&

struct DeclTypeTest
{
	int a;
	static const int b = 5;
};

const DeclTypeTest getTest();

decltype(getTest()) h = DeclTypeTest();		//const DeclTypeTest

关于左值、右值、x值的概念,我会在接下来的文章中进行介绍,根据推导规则2,推导的类型为函数的返回值类型。但是e的类型为int而不是const int,但是h为const DeclTypeTest类型。这是因为对于纯右值pod类型将忽略const/volatile限定,类类型保留。

推导规则3

struct MyStruct
{
	int a;
};

const MyStruct str = MyStruct();

decltype(str.a) a = 0;		//int
decltype((str.a)) b = a;	//const int&

a的结果参考推导规则1,b与a的差别在于在使用decltype的时候使用了括号表达式,使用了括号表达式,仍为左值,则根据推导规则3,b的类型为一个左值引用类型。str为const限定类型,则str.a是const int类型的左值,所以最后b的类型为const int&。

典型的decltype应用,返回类型后置

我们看一下这个例子

template<typename R, typename TL, typename TR>
R Add(TL tl, TR tr)
{
	return tl + tr;
}

int a = 5;
float b = 5.0;
auto c = Add<decltype(a + b)>(a, b);

这里我们发现一个问题,通常外部调用者不知道函数的具体实现。我们可以试着使用decltype在函数定义时表示出函数的返回值。

template<typename TL, typename TR>
decltype(tl + tr) Add(TL tl, TR tr)
{
	return tl + tr;
}

这样使用是错误的,在计算decltype时还没有对tl和tr进行定义。

这里C++11中提供了返回类型后置的语法,我们看看它是如何使用的

template<typename TL, typename TR>
auto Add(TL tl, TR tr) -> decltype(tl + tr)
{
	return tl + tr;
}

这是使用auto和decltype使用的典型场景。

decltype多用在泛型编程中,更多的用法希望大家多多去发掘~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值