从Folly源码学C++ 11的新特性

两年前Facebook发布了他们的C++库,命名为Folly,这是一个在Facebook内部广泛和可重复使用的C++库组件大集合。

       但很多成熟的C++开源库已经存在了,为什么又引进一个呢?除了这个库的实用性外下面是他们网站上贴出来使用Folly的动机。


       Folly(“Facebook开源代码库”不严格的缩写)是以实用性和高效性为中心设计的C++ 11组件的库。它补充(而不是竞争)了Boost和std.库。实际上,我们只有在需要的东西没有或虽然有却不能满足性能配置要求时才开始定义我们自己的组件。

       下面是Folly为什么要引进另一个矢量类的详细解释的例子。就像Folly开发者所声称的那样,这是一个C++ 11组件库,如果你看看他们的源代码就会完全明白,C++ 11特性被广泛地运用在里面。而且几乎所有的C++ 11的新特性都被用到了。

       在c++ 0x几年前刚发布时,我不认为它会给C++语言带来多大影响,但我错了,看看这段Folly里的代码片段,它看起来像是用一门新语言来开发的。

  同样的评论关注几乎所有的Folly源代码,这个实现看起来与c++ 03源代码不同。对有兴趣掌握C++ 11新特性的开发者来说,更好的方式是弄明白成熟的库是怎么使用它们的。

1.auto

       C++ 11使用auto关键字引进了类型推断能力,这意味着在声明变量时编译器就能推断出它们的类型。Folly为几乎所有的变量声明都适配了auto关键字,下面是它源码里的一个例子:


 使用auto关键字能让开发者减少浪费在原来不得不写些编译器已经知道的东西上的时间。

2.nullptr

       常数0已经有着常整数和空指针常量的双重角色。       C++ 11通过引进一个新的关键字来区别空指针常量:nullptr。
       在Folly源码里所有的空指针都通过新的关键字nullptr来表示,没有使用常数0的地方。

3.shared_ptr 

       智能指针不是一个新概念,很多库在多年前就实现了,最通用的一个是boost::shared ptr,它的标准化是新的,不再需要去使用外部的库来用智能指针。

       Folly广泛使用了标准化的共享指针,在它的源码中只有少数的原始指针。

4.Strongly-typed enums

       C++里“传统”的枚举在周围范围输出枚举成员,如果同一个范围内两个不同的枚举定义了相同名称的枚举成员,这样可能会导致名称冲突。

       C++ 11引进了enum class关键字。他们再也不会在周围范围内输出枚举成员了。而且我们现在还可以继承一个枚举。

5.static assert

       C++ 11引进了一种在编译时进行测试的新方式,这要使用static_assert关键字,这个特性对模板参数是非常有益的补充条件,如下图这个Folly源码里的模板类:

6.可变参数模板

       可变参数模板是一个能利用任意数量和类型的模板参数的一个模板。类和函数的参数都可以改变。Folly定义了许多可变参数模板,下面是Folly源码里的两个可变参数模板函数:

7.基于范围的for循环

       C++ 11为了支持遍历集合的“对每一个”范式增强了for语句功能。他是代码更简单,更清楚。Folly广泛地使用了这个特性,下面是Folly里的例子:

8初始化列表

       初始化列表在C++ 03里只涉及到了数组,而在C++ 11中就不仅仅用于数组了。接收一个{}列表就是一个函数接收一个标准初始化类型的参数。这有一个将标准初始化列表作为参数传递给函数的例子:

下面是它被调用的示例:

9.noexecpt

       如果一个函数不能抛出异常,或程序不能解决函数抛出的异常,这个函数就可以被声明为noexecpt。
       下面是来自Folly源码的例子:

10.move 

       C++ 11为了区分左值和右值的引用已经引进了右值引用的概念。左值是一个有名字的对象,而右值是一个没名字的对象(临时对象)。move语义允许修改右值。

       为了实现这一点,C++ 11引进了两个特殊的成员函数:移动构造函数和移动赋值操作符。


11.lambda 

       C++ 11提供了创建匿名函数的能力,叫lambda函数,关于这个函数你可以从这里获得更多的细节。

       Folly在很多函数里都用到了lambda,这是它源码里的一个例子:

12.明确默认和删除的特殊成员函数

       在C++ 03里,编译器为那些本身不支持以下特性的类提供了支持:一个默认的构造函数,一个复制的构造函数,一个复制的赋值运算符(=)以及一个析构函数。程序员能通过定义自定义版本来覆盖这些默认值。然而,很少有对这些默认值的创建的控制。让类在本质上成为不可复制的,比如,需要声明一个局部复制构造函数和复制的赋值操作符,而不是定义它们。在C++ 11里面,可以禁用某些功能,比如,下面的类型是不可复制的,这会让代码变得更简单明了。

13.覆盖标识

       在C++ 11里面,当一个开发者打算重写一个基类函数时可能会无意中创建一个新的虚函数。重新创建的特殊标识意味着编译器会检查基类,以查看是否有完全相同签名的虚函数。如果没有,编译器将会报错。
Folly广泛地应用了这项新特性:

14.std::thread

       C++ 11提供了一个线程类(std::thread),带了一个函数对象,还有可选的传递给它的一系列参数,在新的线程类里运行。

       在C++ 11里操作线程变得更简单了,下面是一个Folly源码里的例子,定义一个新线程的标准方法:

15.无序容器

       无序容器是一种哈希表。C++ 11提供了四种标准:

unordered_map

unordered_set

unordered_multimap

unordered_multiset

       Folly在很多地方用到了这种新容器:

总结

       Folly几乎用到了C++ 11所有的新特性,探索这个源码会给你关于C++ 11新特性更好的主意以及它们是怎么实现的。我鼓励任何对C++ 11感兴趣的开发者去下载Folly的源码,然后来发掘这门新语言的强大力量。
 
原文: Learn from Folly source code the new C++11 features.
译文: http://www.php100.com/html/it/focus/2014/1031/7680.html


你可能感兴趣的:(C++)