C++ 11 decltype 与auto

本文详细介绍了C++11的新特性——类型推导,重点讨论了auto与decltype的区别和用法。auto在推导时会去掉CV属性与引用,对于std::initializer_list有特殊处理。当auto后跟引用时,会发生引用折叠。而decltype则会保留CV属性,对于容器类操作,常会产生引用类型。在C++14中,可以使用decltype(auto)结合两者特性。
摘要由CSDN通过智能技术生成

c++11 新特性中,用的比较多的应该是类型推导了,类型推导有两种,auto与decltype,先说说auto.

1: auto

auto在使用时,最需要注意的应该auto会去掉CV(const , volatile)属性与引用,细说的话有三种情况:

1:auto 后没有引用或指针
int a = 1;
const int ca = 1;
const int &caref = 1;
auto a1 = a;
auto a2 = ca;
auto a3 = caref;

template<typename T>
void f(T para);
f(a);
f(ca);
f(caref);

上述的auto, 都被推导为int,事实上,auto类型推导与模板类型推导是一样的,上面的模板函数T,也都会被推导为int。这其实是合理的。这里有一点值得注意:

int a[10];
auto b = a;

template<typename T>
f(T para);

f(a);

这里会发送类型退化,即auto 和T被推导成int*,对于传递函数来说也会发生类型退化,退化成函数指针。

还有一点不同的就是std::initializer_list,由于c++11为了支持统一初始化,现在POD 类型也可用花括号初始化:

auto a = {1} // std::initalizer_list<int>
auto b(1); // int;

但是模板推导的话,不会假设这是std::initalizer_list,而是报错,这是auto与模板的不同。

2:auto后有引用,但不是万能引用:
int a = 1;
const int ca = 1;
const int &caref = 1;
auto& a1 = a; // int &
auto& a2 = ca; //const int &
auto& a3 = caref; // const int &

template<typename T>
void f(T& para);
f(a); // int &
f(ca); // const int &
f(caref);	// const int &

auto与模板是一样的,带引用的话就会带上CV属性,有时可能会对a3的推导产生疑惑,因为auto后面有个引用,caref 本身有个引用,好像auto最终应该有两个引用,这里是因为有引用折叠。 对于数组类型,这里不会发生类型退化,而是会变成:

int a[10];

auto &a2 = a; // int (&)[10];

这里推导的类型是完整的,带长度信息的,对于模板推导也是如此,由此可以实现一个函数,如同sizeof:

template<typename T, size_t N>
constexpr size_t arraySize(T (&)[N]) {
	return N;
}

这里也是在编译时计算,和sizeof效果一样。

3 auto后跟万能引用
int a = 1;
const int ca = 1;
const int &ra = ca;

auto&& ref1 = a; // int&
auto&& ref2 = ca; // const int &
auto&& ref3 = ra;	// const int&
auto&& ref4 = 1;	// int &&

这里和万能引用的推导是一样的。

2: decltype

declytype与 auto 推导规则不一样,decltype 不会去掉CV属性,而是会推导出和原来变量类型一模一样的类型。比如:

const int i;
decltype(i) a = 1;

这里的a 就是const int;
值得注意的是对于容器类操作,或者说会产生左值的操作,decltype都会推导出引用,比如:

vector<int> vec;
decltype(vec[0]); // int&
int a;
decltype((a)); //  两个括号,一个括号是左值表达式,所以推出int&

这有时可能是有问题的,比如对于vector<bool>, decltype(vec[0])的话,返回的不是bool&,而是vector内部实现的一种代理类,因为vector对bool类型有优化,为了对用户屏蔽,返回了一种代理类,通过代理类去读写,然而decltype会直接推导成代理类。

在c++14中有个写法:

int a = 1;
const int& ref = a;
decltype(auto) ref2 = ref; // const int&;

这表示需要类型推导,但使用decltype的推导规则,这常见于函数返回值的推导。

有时类型推导到底推出什么了,可能不会 确定,这是可以试试typeid(T).name();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值