- 1、>的改进
- 2、auto类型推导
- 3、decltype
- 4、基于范围的for循环
C++11不需要规避>>连续使用;如:vector<2、auto类型推导> vc;
【静态类型】:类型检查发生在编译阶段; 【动态类型】:类型检查发生在运行阶段; 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 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 i=1, j = 1.2; // ❌,由于先推导i为int,而1.2为float3、decltype
typeid
RTTI:即再运行时,它为每一个类型产生一个type_info类型的数据,通过typeid可查; 该机制还包括dynamic_cast; 当该机制会带来运行时开销,提供`-fno-rttion`供用户选择是否关闭;
decltype
(编译时推导)该类型推导需要以一个普通的表达式为参数,返回该表达式的类型; 【应用】: - decltype可以和typedef/using结合为类型定义别名; - 提供程序的可读性和维护性; - 重用匿名类型; - 适用于函数参数中; - 结合auto可以跟踪返回值类型 == result_of::type; 【注意】: - decltype后续的&是多余的,则会被编译器自动忽略; - decltype后的*号不会被编译器忽略; - const和volatic也同样会被编译器忽略;
using size_t = decltype(sizeof(0)); vectorvec; typedef decltype(vec.begin()) vectype; enum {k1, k2}anon_e; decltype(anon_e); template void Sum(T1 &t1, T2 &t2, decltype(t1 + t2) &s) { s = t1 + t2; } template struct result_of { typedef decltype( std::declval ()(std::declval ()...) ) type; }
推导四规则
- 若e没带括号或类成员访问表达式,则decltype(e)为e的实体类型; - 否则,e为T时 - 若e是亡值,则decltype为T&&; - 若e为左值,则decltype为T&; - decltype(e)为T;
追踪返回类型
在泛型编程中,当函数的返回值依赖与实参的类型,那么可以使用decltype来获取; 【注意】: - 在追踪类型中,不用写明作用域;
// 如果将decltype放在auto的位置,那么t1、t2都是未声明,故需要结合auto来使用,在使用复合符号来返回类型 template4、基于范围的for循环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{ }
使用:分为两部分: - :左边为迭代的变量; - :右边为将被迭代的范围; 【注意】: - 要满足被该for使用,需要满足迭代对象实现++和==等操作符; - 范围值可确定的;
int func(int a[]) {
for(auto i : a) { // ❌
cout << i << endl;
}
}
void test() {
int arr[] = {1,3,4};
func(arr);
}



