Bootstrap

常见的C++11特性(一)

常见的C++11新特性

1、初始化列表

传统的C++中,针对不同的类型有不同类型的初始化,下面看几组类型的初始化

// 普通变量初始化
int nType = int(3);
// 普通数组初始化
int nArray[] = {1,2,3,4};
// POD类型初始化 (plain old data,没有构造、析构和虚函数的类或结构体)
struct MyStruct{
	QString sName;
	int nType;
} Simple = {"Kevin", 2};
// 类对象的初始化
class MyClass{
	public:
		QString sName;
		int nType;
};
MyClass classA = MyClass{"Kevin", 2};

为了解决不同类型的初始化,C++11首先把初始化列表的概念绑定到了类型上,并将其称之为 initializer_list,允许构造函数或其他函数像参数一样使用初始化列表,这就为类对象的初始化与普通数组和 POD 的初始化方法提供了统一的桥梁。

// 通过initializer_list初始化列表初始化变量
class MyClass{
	public:
    	MyClass(string name):sName(name),c{2,3,4,2}{};
    private:
    	string sName;
    	int c[4];
   		int *pNumber = new int[]{1,2,3,4};
    	vector<int> vec = {1,2,3};
    	map<int, string> curmap= {{18, "Kevin"},{20, "Tom"}};
};
MyClass Obj{"Jim"}; // 初始化实例化对象

也许有的人会问,C++标准模板库中提供了很多容器,如vector或list,那为什么不直接使用容器自己的构造函数呢,为什么还要使用C++11的initializer_list呢?

接下来我们来看一个例子,假如现在我需要判断一组数据中的最大值,那么该如何计算呢?

在c++11之前,max函数的源程序是这样的:

// 最大值
template <class T> const T& max (const T& a, const T& b);
template <class T, class Compare> const T& max (const T& a, const T& b, Compare comp); 

在c++11之后,max函数的源程序是这样的:

template <class T> T max (initializer_list<T> il);
template <class T, class Compare> T max (initializer_list<T> il, Compare comp);

这说明了什么,说明通过对类模板initializer_list的支持,在计算最大值可以传递更多的参数了。

cout << max({ 54,16,48,5,89}) << endl;   //输出89

尽管有时候通过vector或list容器也可以实现这些功能,但开销最小的最直接的方法是使用initializer_list。

初始化列表initializer_list除了用于构造函数外,还可以作为函数的参数。下面编写一个函数sum来求和,演示该模板类作为函数参数的使用。

#include<iostream>
#include<initializer_list>
using namespace std;

double sum(initializer_list<int> L){
	double tol = 0.0;
	for(auto p = L.begin(); p != L.end(); p++){
		tol += *p;
	}
	return tol;
}

int main(){
	int nTol = sum({1.0, 2, 3, 4.5});
	cout << nTol <<endl;
	return 0;
}
2、范围for或foreach

C++ 11提供了一个特殊版本的 for 循环,在很多情况下,它都可以简化数组的处理,这就是基于范围的 for 循环。在使用基于范围的 for 循环处理数组时,该循环可以自动为数组中的每个元素迭代一次。首先来看下传统数组遍历和范围for的写法。

int numbers[] = {3, 6, 9, 12, 15};
// 传统写法
for (int i=0; i<numbers.size(); ++i)
{
	cout << i << endl;
}

// 范围for写法
for (auto nVal : numbers)
{
	cout << nVal << endl;
}

// foreach写法
foreach (auto nVal , numbers)
{
	cout << nVal << endl;
}

与传统的for循环相比,范围for或foreach不会考虑元素的下标,但是,如果出于某些目的需要使用元素下标时,基于范围的 for 循环或foreach就不能使用了。另外,当遍历多个变量时,也是不能使用的。

参考文章
http://c.biancheng.net/view/1416.html
http://www.cplusplus.com/reference/

;