C++17 – Was gibt’s Neues? Ein Überblick über die wichtigsten Erweiterungen

| Autor / Redakteur: Rainer Grimm * / Sebastian Gerstl

Bild 1: Der Zeitstrahl demonstriert, wie sowohl die C++-Kernsprache als auch die C++-Standardbibliothek deutlich mächtiger geworden sind.
Bild 1: Der Zeitstrahl demonstriert, wie sowohl die C++-Kernsprache als auch die C++-Standardbibliothek deutlich mächtiger geworden sind. (Bild: Rainer Grimm)

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:

Output:

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.

Inhalt des Artikels:

Kommentare werden geladen....

Kommentar zu diesem Artikel

Anonym mitdiskutieren oder einloggen Anmelden

Avatar
  1. Avatar
    Avatar
    Bearbeitet von am
    Bearbeitet von am
    1. Avatar
      Avatar
      Bearbeitet von am
      Bearbeitet von am

Kommentare werden geladen....

Kommentar melden

Melden Sie diesen Kommentar, wenn dieser nicht den Richtlinien entspricht.

Kommentar Freigeben

Der untenstehende Text wird an den Kommentator gesendet, falls dieser eine Email-hinterlegt hat.

Freigabe entfernen

Der untenstehende Text wird an den Kommentator gesendet, falls dieser eine Email-hinterlegt hat.

copyright

Dieser Beitrag ist urheberrechtlich geschützt. Sie wollen ihn für Ihre Zwecke verwenden? Infos finden Sie unter www.mycontentfactory.de (ID: 45095872 / IDEs & Programmiersprachen)