Clang: Vollständige Unterstützung von C++14

von Hubert Schmid vom 2013-11-10

Seit wenigen Tagen unterstützt Clang vollständig den kommenden Sprachstandard C++14 – zumindest mit zwei kleinen Einschränkungen:

Die Änderungen von C++14 gegenüber C++11 sind überschaubar. Hauptsächlich handelt es sich um Verfeinerungen der mit C++11 eingeführten Features – basierend auf den zwischenzeitlich gesammelten Erfahrungen. Drei Erweiterungen sind jedoch hervorzuheben, da sie die Programmierung signifikant beeinflussen werden.

Generic Lambda Expressions

Die Parametertypen anonymer Funktionen müssen mit C++14 nicht mehr angegeben werden. An ihrer Stelle kann das Schlüsselwort auto verwendet werden, analog zur Typinferenz lokaler Variablen.

int n_unseen = std::count_if(messages.begin(), messages.end(), [](auto&& message) { return !message.is_seen(); });

Diese Erweiterung ist hilfreich, da die Parametertypen üblicherweise aus dem Kontext hervorgehen, und ihre explizite Angabe die Lesbarkeit nicht unterstützt. Im Gegenteil: In vielen Situationen ist der Einsatz anonymer Funktionen erst durch den Verzicht auf den Boilerplate sinnvoll.

Generalized Lambda-Capture

Im Gegensatz zu C++11 können anonyme Funktionen in C++14 eigene Variablen definieren, die nicht aus dem Kontext stammen. Die Variablen werden dazu innerhalb der Capture-Liste initialisiert.

auto&& fibonacci = [a=0,b=1]() mutable { auto t = a; a = b; b += t; return t; };

Diese Erweiterung ist besonders sinnvoll, wenn ein Objekt per Move-Operation in die anonyme Funktion verschoben werden soll, oder wenn innerhalb der anonymen Funktion nur Teilobjekte aus dem Kontext benötigt werden. Das Beispiel aus dem Listing ist dagegen eher untypisch.

Function Return Type Deduction

C++14 erweitert die Typinferenz auf die Rückgabetypen von Funktionen und Funktionstemplates. Sowohl bei der Deklaration als auch bei der Definition kann der Rückgabetyp nun in den meisten Fällen entfallen. Im folgenden Listing ist das beispielsweise für inline definierte Member-Funktionen zu sehen.

class rectangle { int _width; int _height; public: auto get_width() const { return _width; } auto get_height() const { return _height; } };

Besonders interessant ist dieses Feature, um lange Wiederholungen zu vermeiden. Im folgenden Funktionstemplate ist der Rückgabetyp vergleichsweise komplex. Innerhalb des Funktionsrumpfs muss er angegeben werden. Die zusätzliche Angabe des Rückgabetyps innerhalb der Signatur würde die Lesbarkeit jedoch nur verschlechtern.

template <typename Iterator> auto make_vector(Iterator first, Iterator last) { return std::vector<std::decay_t<decltype(*first)>>{first, last}; }

Alle diese Erweiterungen werden nun von Clang unterstützt und voraussichtlich Bestandteil der Version 3.4 sein, die noch 2013 veröffentlicht werden soll. In dieser Hinsicht ist Clang klarer Vorreiter und übt Druck auf die Konkurrenz aus. Doch diese lässt nicht lange auf sich warten. Auch GCC und Visual C++ machen gute Fortschritte und werden beide voraussichtlich im Laufe des kommenden Jahres ebenfalls Versionen mit (fast) vollständiger C++14-Unterstützung veröffentlichen.