一, c++ 标准历程:
二, 版本变更编辑
类型推导与auto关键字
1
|
auto
otherVariable = 5;
//otherVariable被按照int型来编译
|
1
|
auto
someStrangeCallableType = boost::bind(&SomeFunction,_2,_1,someObject);
|
1
2
|
int
someInt;
decltype
(someInt) otherIntegerVariable = 5;
|
1
|
for
(vector<
int
>::const_iteratoritr=myvec.begin(); itr!=myvec.end(); ++itr)
|
1
|
for
(
auto
itr = myvec.begin(); itr != myvec.end(); ++itr)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include<vector>
int
main()
{
conststd::vector<
int
>v(1);
auto
a = v[0];
//a为int类型
decltype
(v[0]) b = 0;
//b为constint&类型,即std::vector<int>::operator[](size_type)const的返回类型
auto
c = 0;
//c为int类型
auto
d = c;
//d为int类型
decltype
(c) e;
//e为int类型,c实体的类型
decltype
((c)) f = e;
//f为int&类型,因为(c)是左值
decltype
(0) g;
//g为int类型,因为0是右值
return
0;
}
|
外部模板
1
2
3
4
5
|
int
my_array[5]={1, 2, 3, 4, 5};
for
(
int
& x : my_array)
{
x *= 2;
}
|
三, 掀起C++ 11的神秘面纱
C++标准在1998年获得通过后,有两位委员会委员预言,下一代C++标准将“肯定”包括内置的垃圾回收器(GC),但可能不会支持多线程,因为定义一个可移植的线程模型涉及到的技术太复杂了,13年后,新的C++标准C++11也接近完成,你猜怎么着?让那两位委员没想到的是,本次更新还是没有包括GC,但却包括了一个先进的线程库。C++之父Bjame Stroustrup说C++11就像一个新语言,的确,C++11核心已经发生了巨大的变化,它现在支持Lambda表达式,对象类型自动推断,统一的初始化语法,委托构造函数,deleted和defaulted函数声明nullptr,以及最重要的右值引用。
C++11中值得关注的几大变化
◆ nullptr
◆ 委托构造函数
◆ 右值引用
C++11标准库
C++于2003年以库技术报告1(TR1)的形式经历了重大改版,TR1包括新的容器类(unordered_set,unordered_map,unordered_multiset和unordered_multimap)和多个支撑正则表达式、元组和函数对象封装器等的新库。随着C++11标准获得通过,TR1和自它首次发布以来新增的库被正式纳入标准的C++标准,下面是C++11标准库的一些特性:
线程库
站在程序员的角度来看,C++11最重要的新功能毫无疑问是并行操作,C++11拥有一个代表执行线程的线程类,在并行环境中用于同步,async()函数模板启动并行任务,为线程独特的数据声明thread_local存储类型。如果你想找C++11线程库的快速教程,请阅读Anthony William的“C++0x中更简单的多线程”。
新的智能指针类
C++98只定义了一个智能指针类auto_ptr,它现在已经被废弃了,C++11引入了新的智能指针类shared_ptr和最近添加的unique_ptr,两者都兼容其它标准库组件,因此你可以在标准容器内安全保存这些智能指针,并使用标准算法操作它们。
新的算法
C++11标准库定义了新的算法模仿all_of(),any_of()和none_of()操作,下面列出适用于ispositive()到(first, first+n)范围,且使用all_of(), any_of() and none_of() 检查范围的属性的谓词:
- #include <algorithm>
- //C++11 code
- //are all of the elements positive?
- all_of(first, first+n, ispositive()); //false
- //is there at least one positive element?
- any_of(first, first+n, ispositive());//true
- // are none of the elements positive?
- none_of(first, first+n, ispositive()); //false
一种新型copy_n算法也可用了,使用copy_n()函数,复制一个包含5个元素的数组到另一个数组的代码如下:
- #include
- int source[5]={0,12,34,50,80};
- int target[5];
- //copy 5 elements from source to target
- copy_n(source,5,target);
算法iota()创建了一个值顺序递增的范围,好像分配一个初始值给*first,然后使用前缀++使值递增,在下面的代码中,iota()分配连续值{10,11,12,13,14}给数组arr,并将{‘a’,’b’,’c’}分配给char数组c。
- include <numeric>
- int a[5]={0};
- char c[3]={0};
- iota(a, a+5, 10); //changes a to {10,11,12,13,14}
- iota(c, c+3, 'a'); //{'a','b','c'}
C++11仍然缺乏一些有用的库,如XML API,套接字,GUI,反射以及前面提到的一个合适的自动垃圾回收器,但C++11的确也带来了许多新特性,让C++变得更加安全,高效,易学易用。
如果C++11的变化对你来说太大的话,也不要惊慌,多花些时间逐渐消化这一切,当你完全吸收了C++11的变化后,你可能就会同意Stroustrup的说法:C++11感觉就像一个新语言,一个更好的新语言。
4, 使用C++11的一些理由
如果你的代码工作正常并且表现良好,你可能会想知道为什么还要使用C++ 11。当然了,使用用最新的技术感觉很好,但是事实上它是否值得呢? 在我看来,答案毫无疑问是肯定的。我在下面给出了9个理由,它们分为两类:性能优势和开发效率。
获得性能优势
理由1:move语义(move semantics)。简单的说,它是优化复制的一种方式。有时候复制很显然是浪费的。如果你从一个临时的string对象复制内容,简单的复制指针到字符缓冲区将比创建一个新的缓冲区再复制要高效得多。他之所以能工作是因为源对象超出了范围。
然而,在这以前C++并没有判断源对象是不是临时对象的机制。move语义通过除了复制操作外还允许你有一个move构造函数(move constructor)和一个move赋值运算(move assignment)符来提供这个机制。
你知道吗?当你在Visual Studio 2010中使用标准库中的类如string或vector时,它们已经支持move语义了。这可以防止不必要的的复制从而改善性能。
通过在你的类中实现move语义你可以获得额外的性能提升,比如当你把它们存储到STL容器中时。还有,move语义不仅可以应用到构造函数,还可以应用到方法(如vector的push_back方法)。
理由2:通过使用类别属性(type traits,如is_floating_point)和模板元编程(template metaprogramming,如enable_if template),你可以为某些特定的类型定制模版,这可以实现优化。
理由3:哈希表现在已经是标准实现的了,它提供更快速的插入、删除和查找,这在处理大量数据时很有用。你现在可以随便使用unordered_map, unordered_multimap, unordered_set 和unordered_multiset这几种数据结构了。
提高效率
提高效率不仅都是在代码性能方面,开发时间也是宝贵的。C++ 11可以让你的代码更短、更清晰、和更易于阅读,这可以让你的效率更高。
理由4:auto关键字可以自动推断类型,所以下面的代码:
现在可以很简单的写成:
尽管有些人会说,它隐藏了类型信息,在我看来它利大于弊,因为它减少了视觉混换并展示了代码的行为,还有它可以让你我少打很多字!
理由5:Lambda表达式提供了一种方法来定义匿名方法对象(实际上是闭包),这是代码更加线性和有规律可循。这在和STL算法结合使用时很方便:
bool is_fuel_level_safe()
{
return all_of(_tanks.begin(), _tanks.end(),
[this](Tank& t) { return t.fuel_level() > _min_fuel_level; });
}
理由6:新的智能指针(smart pointer)替换了有问题的auto_ptr,你可以不用担心内存的释放并移除相关释放内存的代码了。这让代码更清晰,并杜绝了内存泄露和查找内存泄露的时间。
理由7:把方法作为first class object是一个非常强大的特性,这让你的代码变得更灵活和通用了。C++的std::function提供了这方面的功能。方法提供一种包装和传递任何可调用的东西-函数指针, 仿函数(functor), lambda表达式等。
理由8:还有许多其它小的功能,如override、final关键字和nullptr让你的代码意图更明确。对我来说,减少视觉混乱和代码中能够更清楚地表达我的意图意味着更高兴、更高效。
另一个开发效率的方面是错误检测。如果你的错误在运行时发生,这意味着你至少需要运行软件,并可能得通过一系列步骤来重现错误,这需要时间。
C++ 11提供了一种方法来检查先决条件并尽早的在可能的时机捕获错误-编译过程中,在你运行代码前。这就是理由9。
这是通过静态断言(static_assert)和类别属性模版实现的。这种方法的另一个好处是,它不需要占用任何的运行时开销,没有什么性能损失!
现在开始掌握C++ 11
在C++ 11标准中除了上描述的还有更多的改动和新功能,它需要一整本数来描述。不过,我相信它们是值得你花时间去学习的。你将省去以往花在提高效率上的时间。很多主流的编译器已经开始支持C++ 11的一些标准了。