C++17 – Was gibt’s Neues? Ein Überblick über die wichtigsten Erweiterungen
Ende 2017 wurde es vollbracht: C++17 ist als neuer ISO-Standard einstimmig verabschiedet. Da stellt sich natürlich die Frage, was gibt es denn an konkreten Neuerungen in C++17? Und wir wirkt sich das für Softwareentwickler aus?

Bevor der hier vorliegende Artikel nun den Blick auf die Details zu C++17 schärft, ist es zuerst notwendig, das große Bild im Auge zu behalten. C++17 setzt die Serie von neuen C++-Standards im Drei-Jahres-Rhythmus konsequent um (siehe Bild 1). Der Zeitstrahl zeigt bereits: Sowohl die C++-Kernsprache als auch die C++-Standardbibliothek sind deutlich mächtiger geworden.
Die verbesserte Kernsprache
Fold expressions, constexpr if, Initialisierer in if und switch Anweisungen, structured binding Deklarationen, automatische Typbestimmung für Konstruktoren von Templates, Vermeindung von Kopieren; die Liste an neuen Features in C++ ist lang. Sowohl für den Anwender als auch für den Bibliotheksautoren in C++ sind viele Perlen dabei.
Fold Expressions
C++11 unterstützt Variadic Templates. Dies sind Templates, die eine beliebige Anzahl an Argumenten annehmen können. Die beliebige Anzahl wird von einem Parameter-Pack gehalten.
Neu ist mit C++17, dass dieses Parameter-Pack direkt mit einem binären Operator zur Übersetzungszeit reduziert werden kann.
#include <iostream>
template<typename... Args>
bool all(Args... args) { return (... && args); }
int main(){
std::cout << std::boolalpha;
std::cout << "all(): " << all() << std::endl;
std::cout << "all(true): " << all(true) << std::endl;
std::cout << "all(true, true, true, false): " << all(true, true, true, false) << std::endl;
std::cout << std::endl;
}
Der binäre Operator des Funktions-Templates all ist das logische UND (&&). Hier ist die Ausgabe des Programms:
all(): true
all(true): true
all(true, true, true, false): false
Es geht mit den Features zur Übersetzungszeit weiter.
Constexpr if
constexpr if erlaubt es, Sourcecode bedingt zu übersetzten.
template <typename T>
auto get_value(T t){
if constexpr (std::is_pointer_v) //(1)
return *t; // deduces return type to int for T = int*
else //(2)
return t; // deduces return type to int for T = int
}
Falls T ein Zeiger ist, dann wird der if Zweig (1) der Funktion get_value übersetzt, falls nicht, der else Zweig (2). Zwei Punkte sind in diesem Zusammenhang wichtig. Die Funktion get_value besitzt zwei verschiedene Rückgabetypen und beide Zweige der if-Anweisungen müssen gültig sein.
Konsequenterweise können if und switch Anweisungen in C++17 das, was for Anweisungen schon lange konnten.
Initialisierer in 'if' und 'switch' Anweisungen
Variablen können in C++17 direkt in if und switch Anweisungen initialisiert werden.
std::map<int,std::string> myMap;
if (auto result = myMap.insert(value); result.second){
/ useResult(result.first);
// ...
}
else{
//...
} // result is automatically destroyed
Die Variable result ist nur innerhalb des if und else Zweigs der if-Anweisung gültig. result verschmutzt daher nicht den umgebenden Bereich.
Falls der Initialisierer in if und switch Anweisungen zusammen mit der structured binding Deklaration zum Einsatz kommt, wird die C++ Syntax noch eleganter.
Structurted binding Deklarationen
Dank structured binding lässt sich direkt ein std::tuple oder ein struct an eine Variable binden. Damit wird das vorherige Beispiel deutlich lesbarer.
std::map<int,std::string> myMap;
if (auto [iter, succeeded] = myMap.insert(value); succeeded) {// (1)
useIter(iter);
// ...
}
else{
//...
} //iter and succeded are automatically be destroyed
auto [iter, succeeded] (1) erzeugt automatisch die zwei Variablen iter und succeeded. In der letzten Zeile werden sie wieder gelöscht.
Das ist ein Feature in C++17, mit dem Programmieren leichter von der Hand wird. Das gleiche gilt für die automatische Template-Typ Ableitung von Konstruktoren.
(ID:45095872)