© best_vector/Shutterstock.com
Wozu brauchen wir Concepts in C++ 20?

Spezifikationen für Typen


Auf Deutsch steht das Wort Konzept laut www.wiktionary.org für „formuliertes Gedankengerüst zur Realisierung von etwas“. Im Englischen geht es aber auch etwas profaner und „Concept“ kann auch einfach nur Begriff oder Begrifflichkeit bedeuten, wie zum Beispiel das „Concept of a Team“. Das Wort wurde schon 1998 von Alexander Stepanov beim Entwurf der STL benutzt, um auszudrücken, dass man die Eigenschaften von Typen beschreiben kann, ohne eine (abstrakte) Basisklasse festzulegen.

Ein Beispiel für Typen ohne festgelegte Basisklassen sind Iteratoren. Obwohl es viele unterschiedliche Implementierung dafür geben kann und diese weitgehend gleich verarbeitet werden können, existiert keine gemeinsame Basisklasse. Trotzdem kann man festhalten, dass ein Iterator einen Inkrementoperator und einen Dereferenzierungsoperator benötigt, dass er vergleichbar sein muss und außerdem konstruierbar (copy-constructable), zuweisbar (copy-assignable) und zerstörbar (destructible). Diese Eigenschaften wurden bisher aber nur informell als Dokumentation im Standard festgelegt. Schon seit Längerem hat die C++-Gemeinde deshalb daran gearbeitet, solche Concepts als Programmcode auszudrücken. Mit C++ 20 ist es nun endlich so weit. In diesem Beitrag erhalten Sie die Antworten auf die drei entscheidenden Fragen: Wie kann man Eigenschaften eines Typs spezifizieren, ohne ihn durch Ableitung an eine Basisklasse zu fesseln? Wie kann man diese Einschränkungen dann nutzen? Und warum brauchen wir das überhaupt?

Beginnen wir mit der letzten Frage. Bisher haben Sie gemeinsame Eigenschaften von Typen durch ein Interface bzw. abstrakte Basisklasse definiert. Auf diese Weise lassen sich Methoden und Operatoren eines Typs vorgeben. Über die Konstruktoren legen Sie fest, ob der Typ konstruierbar, kopierbar oder verschiebbar ist. Ob die Instanzen vergleichbar sind, folgt aus den vorgegebenen Operatoren und so weiter und so weiter. Reichen die Möglichkeiten eines gemeinsamen Interfaces trotzdem nicht aus?

Doch, im Grunde schon. Die Schwierigkeit liegt daran, dass eine gemeinsame Basisklasse Typen zu sehr aneinander bindet und eine starke Abhängigkeit bedeutet, die eigentlich gar nicht notwendig ist. Denken Sie zum Beispiel an Iteratoren: Containerklassen aus den unterschiedlichsten Bereichen und Bibliotheken müssten ihre Iteratoren von einer gemeinsamen Basisklasse ableiten und wären sehr empfindlich von einer Änderung derselben abhängig. In diesem speziellen Fall könnte man das Problem noch dadurch lös...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang