自从c11出来之后一直也没有很系统的学习一下里面的新的特性,现在准备开几篇博文来记录一下,大部分的东西是从官方文档中翻译过来的,如果英语比较好,还是建议大家去读官方的文档,水平有限,总结的可能有些拙劣,还望海涵!
首先对于auto关键字功能的一个扩充:
在了解新特性之前我们有必要再去总结一下,之前auto关键字的作用:
auto:用来声明自动变量。它是存储类型标识符,表明变量(自动)具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型。
其实大多普通声明方式声明的变量都是auto变量,他们不需要明确指定auto关键字,默认就是auto的了。auto变量在离开作用域是会变程序自动释放,不会发生内存溢出情况(除了包含指针的类)。使用auto变量的优势是不需要去考虑变量是否被释放,比较安全。
new:new是用来在堆上申请内存地址的关键字,他产生的变量不会自动释放,除非delete来手动释放,或者程序结束时由操作系统释放,使用new的优势是内存使用比较灵活,理论可以申请任意大小的内存区块(实际与操作系统有关),但这很容易产生问题,一不小心忘记释放对象,特别是在频繁调用的函数内创建的对象忘记释放时,会产生内存溢出,严重时导致程序出错,系统崩溃。但是现在也有很多的方法避免这些问题,如智能指针,用对象来管理内存,其实这些智能指针对象严格意义来讲也可以算是auto类型(仁者见仁),这里不在多说了
。
以上是对于之前auto用法和作用的一点总结,欢迎补充:
c11的auto加入了根据初始化的值的类型来推断变量类型的功能,什么意思呢?举个例子:
以前我们要保存10这个数值,我们必须声明一个int型的变量a:
int a = 10;
我们要保存一个2.1这样的数值,我们必须声明一个float或者double型的变量b:
double b = 2.1;
现在我们可以用auto来实现这样的功能
auto a = 10
auto a = 2.1
你不用显示的指定a的类型,编译器会自动根据你初始化的数值来定义a的类型。
有人会觉得这样的功能很鸡肋呀,我既然要用10,我肯定知道我要使用的是一个整数类型呀,不需要编译器去推断呀?的确,但是某些时候,你可能不知道用户输入数值的类型,尤其是在泛型编程中,就体现出了auto的便捷了,我们再来看个例子:
-
template<class T> void printall(const vector<T>& v)
-
{
-
for (typename vector<T>::const_iterator p = v.begin(); p!=v.end(); ++p)
-
cout << *p << "\n";
-
}
我们在c11之前要在一个模板函数里面,遍历用户传来的容器中的元素,我们必须这样声明一个迭代器:
typename vector<T>::const_iterator p = v.begin()
因为编译器,不能推断用户输入的类型,但是现在有了auto这个东西,一切就变得很简单了:
-
template<class T> void printall(const vector<T>& v)
-
{
-
for (auto p = v.begin(); p!=v.end(); ++p)
-
cout << *p << "\n";
-
}
我们只需要将这个迭代器变量声明成一个auto类型,剩下的工作就交给编译器去做好了,是不是有种“清新爽洁不紧绷”的感觉!
不仅仅能够做这些,还有好戏在后头,因为它还能进行更强大的推理:
-
template<class T, class U> void multiply(const vector<T>& vt, const vector<U>& vu)
-
{
-
// ...
-
auto tmp = vt[i]*vu[i];
-
// ...
-
}
没有auto的时候我们真的很难处理这样的问题,例如:
multiply(double, int)
multiply(int, double)
为了处理上述的两种情况(要尽可能的保证结果的精度)我们很可能需要两个函数来处理,现在有了auto,用一个模板就能轻松搞定上述的问题:因为你不用操心我应该如何定义vt[i]*vu[i]返回值类型的问题了,是不是很cool!
不知道大家对于遍历数组的操作是不是感到很繁琐,对于这个问题我们在c11可以这样轻松的实现:
-
int a[10] = {1,2,3,4,5,6,7,8,9,0};
-
for(auto x : a)
-
{
-
cout << x << " ";
-
}
-
cout << endl;
我们还能这样操作一个容器:
-
void f(vector<double>& v)
-
{
-
for (auto x : v) cout << x << '\n';
-
for (auto& x : v) ++x; // using a reference to allow us to change the value
-
}
我们甚至还可以这样来玩:
-
for (const auto x : { 1,2,3,5,8,13,21,34 }) cout << x << '\n';
总之,自从有了auto腰不酸了,腿不疼了,连碼代码都更有劲了!
阅读(10219) | 评论(0) | 转发(0) |