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.
FĂŒr C++26 sind neben den groĂen ErgĂ€nzungen Reflection und Contracts, die ich in den vergangenen Wochen vorgestellt habe [1], 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 [2] 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 [3])
URL dieses Artikels:
https://www.heise.de/-9991701
Links in diesem Artikel:
[1] https://www.heise.de/developer/ModernesCplusplus-3691794.html
[2] https://en.cppreference.com/w/cpp/language/charset#Basic_character_set
[3] mailto:rme@ix.de
Copyright © 2024 Heise Medien