Ein Überblick über C++26: die Bibliothek
Im vorangegangenen Beitrag habe ich einen Überblick über die Kernsprache von C++26 gegeben. Heute stelle ich die Bibliothek vor.

(Bild: Chinnapong/Shutterstock.com)
- Rainer Grimm
Wie schon in meinen Ausführungen zur Kernsprache von C++26 betont, kann ich auch von der Bibliothek nur einen ersten Eindruck vermitteln, da der Design-Freeze von C++26 erst im ersten Quartal 2025 erfolgen wird. Um es kurz zu machen: Die Bibliothek bietet nicht so leistungsstarke Features wie die Kernsprache. Die Codebeispiele stammen noch aus den Proposals.
std::string-
und std::string_view-
Verarbeitung
Die Funktionen rund um std::string
und std::string_view
machen das Verwenden dieser Funktionen bequemer.
Erfolgs- oder Fehlertest der <charconv
>-chars-Funktionen
Das Verwenden der Funktionen to_chars
oder from_chars
war bisher ziemlich umständlich. Man musste mit res.ec == std::errc{}
den Erfolg der Konvertierung überprüfen. Mit C++26 lässt sich das Ergebnis nach bool
konvertieren.
Arithmetische Überladungen von std::to_string
und Verwendung von std::format
std::to_string
wirft ein paar Probleme auf: "the choice of the floating-point format makes std::to_string of very limited use in practice" (Published Proposal P2587R3).
auto loc = std::locale("uk_UA.UTF-8");
std::locale::global(loc);
std::cout.imbue(loc);
setlocale(LC_ALL, "C");
std::cout << "iostreams:\n";
std::cout << 1234 << "\n";
std::cout << 1234.5 << "\n";
std::cout << "\nto_string:\n";
std::cout << std::to_string(1234) << "\n";
std::cout << std::to_string(1234.5) << "\n";
setlocale(LC_ALL, "uk_UA.UTF-8");
std::cout << "\nto_string (uk_UA.UTF-8 C locale):\n";
std::cout << std::to_string(1234) << "\n";
std::cout << std::to_string(1234.5) << "\n";
Das Programm im vorangehenden Listing zeigt, dass die Ausgabe von Gleitkommaüberladungen für iostreams inkonsistent ist. Es übernimmt den Dezimalpunkt aus der globalen C-Lokale.
Verknüpfung von Stringstreams mit std::string_view
Dank des Proposal P2495R3 kann ein Stringstream aus einem std::string_view
erstellt werden. Im folgenden Beispiel ist ""sv
ein leeres string_view
-Literal.
// implicitly convertable to string_view
const mystring str;
stringstream s1(""sv);
stringstream s1(str);
s2.str(""sv);
Verkettung von Strings und String-Views
Mit C++26 können Strings und String-Views verkettet werden.
std::string calculate(std::string_view prefix)
{
return prefix + get_string(); // NO ERROR
}
Format-Erweiterungen
Zeiger
In älteren C++-Versionen vor C++26 sind nur die Datentypen void
, const void
und std::nullptr_t
gültig. Wenn die Adresse eines beliebigen Zeigers dargestellt werden soll, muss dieser in std::string calculate(std::string_view prefix) { return prefix + get_string(); // NO ERROR }
umgewandelt werden.
double d = 123.456789;
std::format("{}", &d); // ERROR
std::format("{}", static_cast<void*>(&d)); // okay
std::format("{}", static_cast<const void*>(&d)); // okay
std::format("{}", nullptr); // okay
Mit C++26 verschwinden die Fehlermeldungen.
// pointerFormat.cpp
#include <format>
#include <iostream>
int main() {
std::cout << '\n';
double d = 123.456789;
std::cout << std::format("{}", static_cast<void*>(&d)) << '\n';
std::cout << std::format("{}", static_cast<const void*>(&d)) << '\n';
std::cout << std::format("{}", nullptr) << '\n';
std::cout << '\n';
}
Die Ausgabe des Programms sieht dann folgendermaßen aus:
std::filesystem::path
std::format
kann std::filesystem::path
-Objekte anzeigen – wie das Beispiel aus dem Proposal P2845R8 verdeutlicht:
auto p1 = std::filesystem::path("/usr/bin");
Ja std::cout << std::format("{}", p1); // /usr/bin
auto p2 = std::filesystem::path("multi\nline");
std::cout << std::format("{}", p2); // multi
// line
auto p3 = std::filesystem::path("multi\nline");
std::cout << std::format("{:?}", p3); // "multi\nline"
Dank des Formatstring "{:?}"
in der letzten Zeile wird die Escape-Sequenz "\n"
nicht interpretiert.
std::inplace_vector
std::inplace_vector
ist laut Proposal P0843R8 "ein dynamisch anpassbarer Vektor mit einer zur Compilezeit festgelegten Kapazität und zusammenhängendem eingebettetem Speicher, in dem die Elemente innerhalb des Vektorobjekts selbst gespeichert werden" ("a dynamically-resizable vector with compile-time fixed capacity and contiguous embedded storage in which the elements are stored within the vector object itself").
Dieser Container kann als direkter Ersatz für std::vector
verwendet werden. Wann aber sollten inplace_vector
oder vector
zum Einsatz kommen?
Ein Blick in das Proposal P0843R8 liefert die Antwort:
- Speicherzuweisung ist nicht möglich, z. B. in eingebetteten Umgebungen ohne freien Speicher, in denen nur ein Stack und das statische Speichersegment verfügbar sind.
- die Speicherzuweisung eine inakzeptable Beeinträchtigung der Performanz darstellt, z. B. in Bezug auf die Latenz,
- die Zuordnung von Objekten mit komplexen Lebensdauern im statischen Speichersegment erforderlich ist,
std::array
ist keine Option, z. B. wenn nicht standardmäßige konstruierbare Objekte gespeichert werden müssen,- ein dynamisch anpassbares Array innerhalb von
constexpr
-Funktionen erforderlich ist, - muss der Speicherort der
inplace_vector
-Elemente innerhalb desinplace_vector
-Objekts selbst liegen (z. B. zur Unterstützung vonmemcpy
für Serialisierungszwecke).
Verbesserungen der Ranges
Die ranges-Bibliothek erhält neue Funktionen: std::ranges::generate_random
und std::ranges::concat_view.
Der Aufruf std::ranges::generate_random(fltArray, g, d)
verwendet den Generator g
und die Verteilung d
, um die Zufallszahlen zu erzeugen. Der Aufruf ist gleichbedeutend mit der folgenden Schleife:
for(auto& el : fltArray)
el = d(e);
constexpr-
Erweiterungen
Seit C++11 setzt sich ein Trend fort: Immer mehr Funktionsaufrufe werden in C++ zu constexpr
.
std::stable_sort, std::stable partition
undstd::inplace_merge
sind in C++26constexpr
. Dies gilt auch für ihre Pendants in der ranges-Bibliothek.
- Das Proposal P1383R2 führt aus: "This proposal amounts to a (further) liberal sprinkling of constexpr in <cmath>, together with a smattering in <complex>".
Wie geht es weiter?
In meinem nächsten Beitrag setze ich meine Reise durch die Bibliothek in C++26 fort. (map)