User-defined Literals for C++ Standard Library Types

von Hubert Schmid vom 2013-03-17

Bereits für 2014 ist die nächste Aktualisierung der C++-Standardbibliothek angedacht. Es ist zwar noch offen, was sich in diesem Zuge ändern wird. Doch sehr wahrscheinlich ist, dass Benutzer-definierte Literale für Klassen der Standardbibliothek kommen werden, die unter der Nummer N3531 bekannt sind.

Die benötigte Sprachunterstützung gibt es bereits seit C++11. Für die Anpassungen der Standardbibliothek reichte die Zeit allerdings nicht mehr. Mit N3531 werden sie jetzt für Zeichenketten, komplexe Zahlen und Zeitdauern nachgereicht. Das ist erfreulich, denn an dieser Stelle führt die Standardisierung zu einer Vereinheitlichung, erhöht den Wiedererkennungswert und verbessert die Lesbarkeit.

std::basic_string

In C++ sind Zeichenkettenliterale genauso wie in C keine Objekte sondern char-Arrays. Ihre Verwendung ist entsprechend schwerfällig. Doch das ändert sich mit den Benutzer-definierten Literalen: In Zukunft reicht das Suffix s, um ein std::string-Objekt zu erzeugen.

using namespace std::string_literals; auto greeting = "othello"s.substr(2) + ' ' + "underworld"s.substr(5); std::cout << greeting << '\n';

Dadurch können die std::string-Methoden bequem und ohne expliziten Aufruf des Konstruktors verwendet werden. Das Gleiche funktioniert auch für Zeichenketten mit anderen Standard-Kodierungen.

auto a = L"Hello World"s; // std::wstring auto b = u"Hello World"s; // std::u16string auto c = U"Hello World"s; // std::u32string

std::complex

Literale für komplexe Zahlen werden bisher nur durch proprietäre Erweiterungen einiger Compiler unterstützt. Mit der Erweiterung für Benutzer-definierte Literale gibt es nun eine einheitliche Notation. Neben dem Suffix i für den imaginären Anteil von std::complex<double> gibt es noch il für std::complex<long double> und i_f für std::complex<float>.

using namespace std::complex_literals; std::cout << sqrt(2.3 + 4.5i) << '\n';

std::chrono::duration

Besonders hilfreich sind Benutzer-definierte Literale für Zeitangaben. Dadurch werden die verwendeten Einheiten erstens transparent, und lassen sich zweitens einfacher kombinieren. Die drei sleep_for-Aufrufe im folgenden Code-Fragment sollten alle den aktuellen Thread für 1,2 Sekunden blockieren:

using namespace std::chrono_literals; std::this_thread::sleep_for(1.2s); std::this_thread::sleep_for(1s + 200ms); std::this_thread::sleep_for(2.0minutes / 100);

Das Dokument N3531 sieht Literale mit den Endungen h, minutes, s, ms, us und ns für die entsprechenden Einheiten vor – sowohl für ganzzahlige als auch für Gleitkommawerte. Das ist eine großartige Sache – vor allem wenn man sie mit den Idiomen für Zeitangaben anderer Programmiersprachen vergleicht.