2011年C++11的标准发布,广大C++开发者开始关注新标准中的C++特性;而这些新特性给这门历史悠久的语言带来了生机和活力,用C++之父 Bjarne Stroustrup 的话:“这次更新已经让C++看起来像一门新的语言了”
auto关键字的进化
auto关键字在历史上(早期C/C++)用于指定变量存储属性为自动类型,即变量自动创建自动销毁;换句话,auto用于声明栈变量(局部变量)。随着时间的流逝和编译技术的发展,栈变量的定义不再需要auto关键字,栈变量的属性默认为自动的;因此,auto关键字逐渐退出历史舞台,工程开发中几乎无人使用。C++11给这个古老的关键字赋予了新的意义:auto可用于定义有初始值的变量,编译器根据初始值自动推导变量类型。
#include <iostream>
#include <algorithm>
using namespace std;
double func()
{
double ret = 0.0;
return ret;
}
void main()
{
auto x = 1; // x为int
auto y = x; // y为int
//auto z; // 这样的写法是错误的,因为没有初始值来确定z的类型
auto p = &x; // p的类型为 int*
auto& r = y; //r的类型为 int&
double func(); //声明
auto f = func();
auto m = f + r; //r为int类型,f为double类型,所以由于隐试类型转换,m为double
cout << typeid(x).name() << endl;
cout << typeid(y).name() << endl;
cout << typeid(p).name() << endl;
cout << typeid(r).name() << endl;
cout << typeid(f).name() << endl;
cout << typeid(m).name() << endl;
cin.get();
}
注意:
-
编译器自动推导类型,结果为静态类型
-
auto只是一个具体类型的占位符
-
auto不能定义无初始值的变量
类型推导关键字decltype
C++11新增了decltype关键字,用来在编译阶段推导一个表达式的结果类型,并且能够使用这个结果类型定义变量。
/*
*/
#include <iostream>
using namespace std;
void main()
{
int x = 0;
decltype(x) y = 1; //y-->int
decltype(x + y) z = 2; //z-->int
const int& i = z;
decltype(i) j = y; //j-->const int&
decltype(z)* px = &x; //px-->int*
cout << typeid(x).name() << endl;//int
cout << typeid(y).name() << endl;//int
cout << typeid(z).name() << endl;//int
cout << typeid(i).name() << endl;//int
cout << typeid(j).name() << endl;//int const只是在编辑期间有用,在运行期间无效
cout << typeid(px).name() << endl;//int*
cin.get();
}
decltype并不会真正计算括号中表达式的值,而是在编译阶段通过表达式中的操作数推导出结果类型,这一点与sizeof关键字类似;另外,值得注意的是delctype与经典C++中的关键字typeid完全不同;typeid是动态类型识别关键字,在运行阶段将变量的类型信息保存到一个type_info对象中。
示例:
#include <iostream>
using namespace std;
void main()
{
int i = 0;
decltype(i) j = 0; //j-->int
cout << typeid(j).name() << endl; //int
char d = 'D';
short s = 2;
decltype(d + s) r = 0; //r-->int
cout << typeid(r).name() << endl; //int
cin.get();
}
在实际工程开发中,通过decltype关键字能够复用代码中的匿名类型(anonymous type)
#include <iostream>
using namespace std;
struct
{
int id;
int score;
} a[100]; //a是一个结构体数组,是一个匿名类型
void main()
{
decltype(a) b;
b[0].id = 1;
b[0].score = 99;
cout << typeid(a).name() << endl;
cout << typeid(b).name() << endl;
cout << sizeof(a) << endl;
cout << sizeof(a) / sizeof(*a) << endl;
cin.get();
}
示例中的a是一个结构体数组,每一个元素的类型为匿名结构体。在经典C++中,a的类型无法再次使用;但是在C++11中,decltype关键字使得匿名类型的复用成为可能。