【C++11新特性】| 【04】auto、decltype类型推导以及for

本文介绍了C++11的一些重要改进,包括右移操作符的改进,允许连续使用;auto类型的推导简化了代码并支持泛型编程;decltype提供了编译时类型推导,增强了程序的可读性和维护性;基于范围的for循环简化了迭代代码。同时,文章探讨了这些特性的使用规则和注意事项。
摘要由CSDN通过智能技术生成

1、>的改进

C++11不需要规避>>连续使用;如:vector<<vector>> vc;

2、auto类型推导

【静态类型】:类型检查发生在编译阶段;
【动态类型】:类型检查发生在运行阶段;
C++11后auto不再是一个存储类型指示符,可以再编译器间推导变量的类型(简化代码);
当使用auto时,必须立即对其进行定义,否则将会出错;
- 能够解决一般的精度问题,例如将float计算的结果推导为double;
- 支持泛型编程;
#define Max1(a, b) ((a) > (b)) ? (a) : (b)
#define Max2(a, b) ({\
		auto _a = (a);\
		auto _b = (b);\
		(_a > _b) ? _a : _b;\
	})
上述使用auto先将结果计算出来能够减少a和b再改运算出现的次数,优化;

使用细则

- auto可以结合指针和引用使用;
- auto可以结合const、volatile使用;
- auto可以再一条语句中声明多个变量;

【auto限制】:
- 不能再函数参数中使用;
- 不能用于非静态成员变量;
- 不能用于数组;
- 不能用于模板参数的实例化vecotr<auto> c {1};
int x;
int *y = &x;
double foo();
int &bar();

auto *a = &x;
auto &b = x;
auto c = y;
auto *d = y;
auto *e =  &foo(); // foo为临时变量❌
auto &f = foo(); // 不能绑定临时变量
auto g= bar();
auto &h = bar();

/** auto声明多个变量 */
auto i=1, j = 1.2; // ❌,由于先推导i为int,而1.2为float

3、decltype

typeid

RTTI:即再运行时,它为每一个类型产生一个type_info类型的数据,通过typeid可查;
该机制还包括dynamic_cast;
当该机制会带来运行时开销,提供`-fno-rttion`供用户选择是否关闭;

decltype

(编译时推导)该类型推导需要以一个普通的表达式为参数,返回该表达式的类型;
【应用】:
	- decltype可以和typedef/using结合为类型定义别名;
	- 提供程序的可读性和维护性;
	- 重用匿名类型;
	- 适用于函数参数中;
	- 结合auto可以跟踪返回值类型 == result_of<T>::type;

【注意】:
	- decltype后续的&是多余的,则会被编译器自动忽略;
	- decltype后的*号不会被编译器忽略;
	- const和volatic也同样会被编译器忽略;
/** 别名 */
using size_t = decltype(sizeof(0));
vector<int> vec;
typedef decltype(vec.begin()) vectype;

/** 重用匿名 */
enum {k1, k2}anon_e;
decltype(anon_e);

/** 函数参数 */
template<class T1, class T2> 
void Sum(T1 &t1, T2 &t2, decltype(t1 + t2) &s) { s = t1 + t2; }

/** result_of推导 */
template<class F, class...ArgTypes>
struct result_of<F(ArgTypes...)> {
	typedef decltype(
		std::declval<F>()(std::declval<ArgTypes>()...)
	) type;
}

推导四规则

- 若e没带括号或类成员访问表达式,则decltype(e)为e的实体类型;
- 否则,e为T时
	- 若e是亡值,则decltype为T&&;
	- 若e为左值,则decltype为T&;
	- decltype(e)为T;

在这里插入图片描述
追踪返回类型

在泛型编程中,当函数的返回值依赖与实参的类型,那么可以使用decltype来获取;
【注意】:
- 在追踪类型中,不用写明作用域;
// 如果将decltype放在auto的位置,那么t1、t2都是未声明,故需要结合auto来使用,在使用复合符号来返回类型
template<typename T1, typename T2>
auto Sum(T1& t1, T2& t2) ->decltyoe(t1 + t2) {
	return t1 + t2;
}

/** 不用写明作用域 */
class OuterType {
    struct InnerType { int i; };
    InnerType GetInner();
    InnerType it;
};

auto OuterType::GetInner() ->InnerType{
    
}

4、基于范围的for循环

使用:分为两部分:
- :左边为迭代的变量;
- :右边为将被迭代的范围;
【注意】:
- 要满足被该for使用,需要满足迭代对象实现++和==等操作符;
- 范围值可确定的;
/** 无法确定a的范围 */
int func(int a[]) {
	for(auto i : a) {	// ❌
		cout << i << endl;
	}
}

void test() {
	int arr[] = {1,3,4};
	func(arr);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jxiepc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值