Vor sechs Jahren veröffentlichte Facebook seine C++-Bibliothek namens Folly, eine umfangreiche Sammlung wiederverwendbarer C++-Bibliothekskomponenten, die intern bei Facebook intensiv eingesetzt werden.
Es gibt jedoch bereits viele ausgereifte Open-Source-Bibliotheken für C++. Warum also noch eine weitere? Auf der Website werden die Beweggründe für ihre Entwicklung wie folgt erläutert:
Folly (der Name ist lose von „Facebook Open Source Library“ abgeleitet) ist eine Bibliothek aus C++11-Komponenten, die mit Blick auf Praxistauglichkeit und Effizienz entwickelt wurde. Sie ergänzt – statt mit ihnen zu konkurrieren – Angebote wie Boost und natürlich std. Tatsächlich entwickeln wir nur dann eine eigene Komponente, wenn etwas, das wir benötigen, entweder nicht verfügbar ist oder nicht das erforderliche Leistungsprofil erfüllt.Hier finden Sie beispielsweise eine ausführliche Erklärung dafür, warum Folly mit FBVector eine weitere Vektorklasse eingeführt hat. Die Folly-Entwickler bezeichnen ihre Bibliothek als Sammlung von C++11-Komponenten – und ein Blick in den Quellcode bestätigt das eindeutig: C++11-Features werden intensiv genutzt, und nahezu alle neuen C++11-Features kommen zum Einsatz.
Als C++0x einige Jahre zuvor angekündigt wurde, dachte ich, es würde die Sprache C++ nicht wesentlich verändern. Damit lag ich falsch. Werfen Sie einen Blick auf diesen Codeausschnitt aus Folly – er wirkt beinahe, als wäre er in einer neuen Sprache geschrieben.

Dasselbe gilt für nahezu den gesamten Folly-Quellcode: Seine Implementierung unterscheidet sich deutlich von C++03-Code.
Für Entwickler, die die neuen C++11-Features beherrschen möchten, ist es besonders hilfreich zu sehen, wie ausgereifte Bibliotheken sie einsetzen. Folly eignet sich hervorragend, um diese Features zu erkunden. Sehen wir uns einige davon im Quellcode an.
1. auto
C++11 führt mit dem Schlüsselwort auto Typinferenz ein: Der Compiler leitet den Typ einer Variablen bei ihrer Deklaration selbst ab. Folly verwendet auto für nahezu alle Variablendeklarationen. Hier ein Beispiel aus dem Quellcode.

Mit dem Schlüsselwort auto müssen Sie weniger Zeit darauf verwenden, Typen explizit anzugeben, die der Compiler ohnehin bereits kennt.
2. nullptr
Die Konstante 0 erfüllte traditionell eine Doppelrolle als Ganzzahlkonstante und Nullzeigerkonstante. C++11 behebt diese Mehrdeutigkeit mit einem eigenen Schlüsselwort für Nullzeiger: nullptr.
Im Folly-Quellcode werden alle Nullzeiger mit dem neuen Schlüsselwort nullptr dargestellt; die Konstante 0 wird dafür nirgends verwendet.
3. shared_ptr
Smart Pointer sind kein neues Konzept; zahlreiche Bibliotheken implementierten sie bereits vor vielen Jahren. Zu den bekanntesten gehört boost::shared_ptr. Neu ist ihre Standardisierung – für die Arbeit mit Smart Pointern ist keine externe Bibliothek mehr erforderlich.
Folly setzt den standardisierten Shared Pointer intensiv ein; im Quellcode finden sich nur noch wenige Raw Pointer.
4. Stark typisierte Enums
„Traditionelle“ Enums in C++ exportieren ihre Enumeratoren in den umgebenden Gültigkeitsbereich. Dadurch können Namenskollisionen entstehen, wenn zwei verschiedene Enums im selben Scope Enumeratoren mit demselben Namen definieren. C++11 führt mit der Syntax enum class bereichsgebundene Enumerationen ein. Deren Enumeratoren werden nicht mehr in den umgebenden Scope exportiert. Außerdem lässt sich nun der zugrunde liegende Typ eines Enums festlegen.

5. static_assert
C++11 führt mit dem neuen Schlüsselwort static_assert eine Möglichkeit ein, Zusicherungen bereits zur Compile-Zeit zu prüfen. Das ist besonders nützlich, um Bedingungen für Template-Parameter festzulegen, wie diese Template-Klasse aus dem Folly-Quellcode zeigt:

6. Variadische Templates
Ein variadisches Template kann eine beliebige Anzahl von Template-Argumenten beliebiger Typen annehmen. Sowohl Klassen als auch Funktionen können variadisch sein. Folly definiert zahlreiche variadische Templates; hier sind zwei variadische Template-Funktionen aus dem Folly-Quellcode:

7. Bereichsbasierte for-Schleifen
C++11 erweitert die for-Anweisung um eine bereichsbasierte Iteration über Collections. Dadurch wird der Code einfacher und übersichtlicher. Folly nutzt dieses Feature intensiv; hier ein Beispiel.

8. Initialisierungslisten
In C++03 gelten Initialisierungslisten nur für Arrays; in C++11 sind sie nicht mehr darauf beschränkt. Um eine {}-Liste entgegenzunehmen, verwendet man eine Funktion – häufig einen Konstruktor – mit einem Argument vom Typ std::initializer_list<T>. Hier ist ein Beispiel für eine Funktion, die std::initializer_list als Argument entgegennimmt.

Und so wird sie aufgerufen.

9. noexcept
Wenn eine Funktion keine Exception auslösen kann oder das Programm nicht darauf ausgelegt ist, von dieser Funktion ausgelöste Exceptions zu behandeln, kann die Funktion als noexcept.
Hier ein Beispiel aus dem Folly-Quellcode.

10. move
C++11 führte Rvalue-Referenzen (mit && angegeben) ein, um Referenzen auf Lvalues von Referenzen auf Rvalues zu unterscheiden. Ein Lvalue ist ein Objekt mit einem Namen, ein Rvalue dagegen ein Objekt ohne Namen – also ein temporäres Objekt. Move-Semantik ermöglicht es, Rvalues zu verändern. Dafür führt C++11 zwei neue spezielle Memberfunktionen ein: den Move-Konstruktor und den Move-Zuweisungsoperator.


Hier finden Sie ein gutes Dokument das die Vorteile der Move-Semantik ausführlicher erläutert.
11. lambda
C++11 ermöglicht das Erstellen anonymer Funktionen, sogenannter Lambda-Funktionen. Weitere Details zu diesem Feature finden Sie hier .
Folly verwendet Lambdas in zahlreichen Funktionen; hier ein Beispiel aus dem Quellcode:

12. Explizit als default oder deleted deklarierte spezielle Memberfunktionen
In C++03 stellt der Compiler für Klassen, die diese nicht selbst definieren, einen Standardkonstruktor, einen Kopierkonstruktor, einen Kopierzuweisungsoperator (operator=) und einen Destruktor bereit. Entwickler können diese Vorgaben durch eigene Implementierungen überschreiben. Allerdings bietet C++03 nur wenig Kontrolle darüber, welche dieser Standardfunktionen erzeugt werden. Um eine Klasse beispielsweise grundsätzlich nicht kopierbar zu machen, mussten ein privater Kopierkonstruktor und Kopierzuweisungsoperator deklariert, aber nicht definiert werden. In C++11 können bestimmte Funktionen explizit deaktiviert werden. Der folgende Typ ist beispielsweise nicht kopierbar, wodurch der Code einfacher und klarer wird.

13. Der Bezeichner override
In C++03 kann versehentlich eine neue virtuelle Funktion entstehen, obwohl eigentlich eine Funktion der Basisklasse überschrieben werden sollte. Der override spezielle Bezeichner veranlasst den Compiler zu prüfen, ob in der oder den Basisklassen eine virtuelle Funktion mit exakt dieser Signatur existiert. Ist das nicht der Fall, meldet der Compiler einen Fehler.
Folly nutzt dieses neue Feature intensiv:

14. std::thread
Eine Thread-Klasse (std::thread) steht zur Verfügung. Sie übernimmt ein Funktionsobjekt sowie optional eine Reihe von Argumenten, die an dieses übergeben werden, und führt es im neuen Thread aus. Mit C++11 ist die Arbeit mit Threads einfacher; dieses Beispiel aus dem Folly-Quellcode zeigt den standardmäßigen Weg, einen neuen Thread zu erzeugen:

15. Ungeordnete Container
Ein ungeordneter Container ist eine Form von Hash-Tabelle. C++11 stellt vier standardisierte Varianten bereit:
- unordered_map
- unordered_set
- unordered_multimap
- unordered_multiset
Folly verwendet diese neuen Container an vielen Stellen.

Fazit
Folly nutzt nahezu alle neuen C++11-Features. Wenn Sie den Quellcode untersuchen, erhalten Sie ein besseres Verständnis der neuen Möglichkeiten von C++ und ihres praktischen Einsatzes.
Ich empfehle jedem C++-Entwickler, der sich für C++11 interessiert, den Folly-Quellcode herunterzuladen und die Möglichkeiten von modernem C++ selbst zu erkunden.
