Softwareentwicklung: Platzhalter und erweiterter Zeichensatz in C++26
Platzhalter sind eine gute Möglichkeit, um Variablen zu markieren, die nicht mehr benötigt werden. Außerdem wird der Zeichensatz von C++26 erweitert.

(Bild: SerbioVas/Shutterstock)
- Rainer Grimm
Für C++26 sind neben den großen Ergänzungen Reflection und Contracts, die ich in den vergangenen Wochen vorgestellt habe, auch ein paar kleinere, nützliche Ergänzungen vorgesehen.
Platzhalter
Strukturierte Bindungen sind ein Feature von C++17, mit dem man mehrere Variablen an die Elemente eines strukturierten Objekts binden kann.
Das folgende Programm demonstriert die Verwendung von Tupeln und strukturierten Bindungen, um mehrere Werte aus einer Funktion zurĂĽckzugeben und wieder auszupacken.
// placeholder1.cpp
#include <tuple>
#include <string>
#include <iostream>
// Function that returns three values
std::tuple<int, std::string, double> getThreeValues() {
int intValue = 42;
std::string strValue = "example";
double doubleValue = 3.14;
return std::make_tuple(intValue, strValue, doubleValue);
}
int main() {
// Retrieve the three values using structured binding
auto [intValue, strValue, doubleValue] = getThreeValues();
// Print the values
std::cout << "Integer: " << intValue << '\n';
std::cout << "String: " << strValue << '\n';
std::cout << "Double: " << doubleValue << '\n';
}
Die Funktion getThreeValues
ist so definiert, dass sie ein Tupel zurückgibt, das drei verschiedene Datentypen enthält: einen int
, einen std::string
und einen double
. Diese Werte werden dann mit std::make_tuple
in ein Tupel gepackt und von der Funktion zurĂĽckgegeben.
In der main
-Funktion ruft das Programm die drei von getThreeValues
zurückgegebenen Werte mithilfe strukturierter Bindungen ab. Strukturierte Bindungen ermöglichen es dem Programm, das Tupel direkt in drei separate Variablen zu packen: intValue
, strValue
und doubleValue
. Das macht den Code lesbarer und einfacher als das manuelle Auspacken des Tupels.
Manchmal braucht man nicht alle drei Werte aus der Funktion getThreeValues
.
// placeholder2.cpp
#include <tuple>
#include <string>
#include <iostream>
// Function that returns three values
std::tuple<int, std::string, double> getThreeValues() {
int intValue = 42;
std::string strValue = "example";
double doubleValue = 3.14;
return std::make_tuple(intValue, strValue, doubleValue);
}
int main() {
// Retrieve the three values using structured binding
auto [_, strValue, doubleValue] = getThreeValues();
// Print the values
std::cout << "String: " << strValue << '\n';
std::cout << "Double: " << doubleValue << '\n';
}
Dieses Mal wird der intValue
aus der Funktion getThreeValues
im nachfolgenden Code nicht benötigt. Aus Konvention binde ich ihn an den Unterstrich.
Das bedeutet gleichzeitig, dass der Compiler keine Warnung ausgibt, weil die Variable _
nicht verwendet wird:
Leider kann das intuitive _
nur einmal als Bezeichner verwendet werden. Diese Einschränkung entfällt mit C++26:
// placeholder3.cpp
#include <tuple>
#include <string>
#include <iostream>
// Function that returns three values
std::tuple<int, std::string, double> getThreeValues() {
int intValue = 42;
std::string strValue = "example";
double doubleValue = 3.14;
return std::make_tuple(intValue, strValue, doubleValue);
}
int main() {
// Retrieve the three values using structured binding
auto [_, strValue, _] = getThreeValues();
// Print the values
std::cout << "String: " << strValue << '\n';
}
In dieser Variante wird weder der intValue
noch der doubleValue
aus der Funktion getThreeValues
benötigt. Ich verwende konsequent zwei Unterstriche.
Erweiterter Zeichensatz
Drei neue Zeichen sind im Basiszeichensatz verfĂĽgbar:
Das folgende Programm verwendet alle drei fĂĽr Raw-String-Literale.
#include <iostream>
int main() {
std::cout << '\n';
auto raw1 = R"@(Hello\n)@";
auto raw2 = R"$(Hello\t)$";
auto raw3 = R"`(Hello\b)`";
std::cout << "raw1: " << raw1 << '\n';
std::cout << "raw2: " << raw2 << '\n';
std::cout << "raw3: " << raw3 << '\n';
std::cout << '\n';
}
Das Programm definiert dann drei Raw-String-Literale: raw1
, raw2
und raw3
. Raw-String-Literale werden in C++ in delimiter(...)delimiter
eingeschlossen, wobei delimiter
eine beliebige Folge von Zeichen sein kann. So kann die Zeichenkette Sonderzeichen wie \n
, \t
oder \b
enthalten, ohne dass sie interpretiert werden mĂĽssen.
raw1
ist definiert alsR„@(Hello\n)@
“, das den TextHello\n
enthält, ohne dass\n
als Zeilenumbruch interpretiert wirdraw2
ist definiert alsR„$(Hello\t)$“
, das den TextHello\t
enthält, ohne\t
als Tabulatorzeichen zu interpretierenraw3
ist definiert alsR„`(Hello\b)`“
, das den TextHello\b
enthält, ohne dass\b
als Backspace interpretiert wird.
Zum Schluss sehen wir die Ausgabe des Programms:
Wie geht's weiter?
Die Kernsprache von C++26 bietet weitere Verbesserungen, wie die Pack-Indexierung, an. Darüber werde ich im nächsten Blogartikel schreiben. (rme)