Structured Bindings
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 88 von 104.
Strukturierte Bindungen, eingeführt in C++17, ermöglichen es Ihnen, mehrere Werte aus Arrays, Pairs, Tuples oder Structs in einer einzigen Deklaration in einzelne benannte Variablen zu entpacken. Dies macht den Code sauberer und lesbarer, wenn man mit zusammengesetzten Daten arbeitet.
Die Syntax verwendet auto mit eckigen Klammern, die die neuen Variablennamen enthalten:
#include <iostream>
#include <map>
#include <tuple>
int main() {
// Entpacken eines Paares
std::pair<std::string, int> person{"Alice", 25};
auto [name, age] = person;
std::cout << name << " is " << age << "\n";
// Entpacken eines Tuples
std::tuple<int, double, char> data{42, 3.14, 'X'};
auto [num, pi, letter] = data;
// Entpacken in bereichsbasierten for-Schleifen
std::map<std::string, int> scores{{"Bob", 90}, {"Carol", 85}};
for (const auto& [student, score] : scores) {
std::cout << student << ": " << score << "\n";
}
}Strukturierte Bindungen funktionieren auch mit Arrays und benutzerdefinierten Structs, die öffentliche Member haben:
struct Point {
double x;
double y;
};
Point getOrigin() { return {0.0, 0.0}; }
int main() {
auto [x, y] = getOrigin();
int arr[3] = {1, 2, 3};
auto [a, b, c] = arr;
}Sie können auto& oder const auto& verwenden, um per Referenz zu binden, wodurch Kopien vermieden werden und bei Bedarf die Änderung der ursprünglichen Werte ermöglicht wird. Diese Funktion ist besonders nützlich beim Iterieren über STL-Container oder beim Umgang mit Funktionen, die mehrere Werte zurückgeben.
Aufgabe
EinfachLassen Sie uns einen Notenanalysator für Studenten erstellen, der die Leistungsfähigkeit von Structured Bindings demonstriert. Sie werden ein System erstellen, das Datensätze von Studenten und Kursdaten verarbeitet und dabei Structured Bindings verwendet, um Paare, Tupel und Structs in Ihrem gesamten Code elegant zu entpacken.
Sie werden Ihren Code über drei Dateien organisieren:
Student.h: Definieren Sie einStudent-Struct mit öffentlichen Membern für den Namen des Studenten (std::string), die ID (int) und den Notendurchschnitt (double). Erstellen Sie außerdem eine Funktion namenscreateStudent, die einen Namen, eine ID und einen Notendurchschnitt entgegennimmt und einStudent-Struct zurückgibt.GradeUtils.h: Erstellen Sie Hilfsfunktionen für die Notenverarbeitung.Definieren Sie eine Funktion
getGradeInfo, die eine numerische Punktzahl (Integer) entgegennimmt und einstd::tuplezurückgibt, das drei Werte enthält: die Note als Buchstabe (std::string), die Notenpunkte (double) und ob bestanden wurde (bool). Verwenden Sie diese Notenskala:- 90+ : "A", 4.0, true
- 80-89: "B", 3.0, true
- 70-79: "C", 2.0, true
- 60-69: "D", 1.0, true
- Unter 60: "F", 0.0, false
Definieren Sie außerdem eine Funktion
makeScorePair, die einen Kursnamen (std::string) und eine Punktzahl (int) entgegennimmt und einstd::pairdieser Werte zurückgibt.main.cpp: Lesen Sie vier Eingaben ein:- Name des Studenten (String)
- Studenten-ID (Integer)
- Kursname (String)
- Punktzahl (Integer)
Verwenden Sie Structured Bindings in Ihrer gesamten Main-Funktion:
- Rufen Sie
createStudentmit dem Namen, der ID und einem Platzhalter-Notendurchschnitt von 0.0 auf. Verwenden Sie Structured Bindings, um das zurückgegebene Struct in einzelne Variablen zu entpacken, und geben Sie dann aus:Student: [name] (ID: [id]) - Rufen Sie
makeScorePairmit dem Kursnamen und der Punktzahl auf. Verwenden Sie Structured Bindings, um das Paar zu entpacken, und geben Sie dann aus:Course: [course], Score: [score] - Rufen Sie
getGradeInfomit der Punktzahl auf. Verwenden Sie Structured Bindings, um alle drei Tupelelemente zu entpacken, und geben Sie dann aus:(Geben Sie "yes" aus, wenn passing true ist, "no" wenn false)Grade: [letter] Points: [points] Passing: [yes/no]
Zum Beispiel mit den Eingaben Alice, 1001, Math und 85:
Student: Alice (ID: 1001)
Course: Math, Score: 85
Grade: B
Points: 3
Passing: yesMit den Eingaben Bob, 2002, Physics und 55:
Student: Bob (ID: 2002)
Course: Physics, Score: 55
Grade: F
Points: 0
Passing: noDenken Sie daran, <tuple> und <utility> einzubinden, wo es erforderlich ist. Die entscheidende Erkenntnis ist, wie Structured Bindings es Ihnen ermöglichen, zusammengesetzte Typen – Paare, Tupel und Structs – in einer einzigen, lesbaren Deklaration in benannte Variablen zu entpacken.
Spickzettel
Structured Bindings (C++17) ermöglichen das Entpacken mehrerer Werte aus Arrays, Pairs, Tuples oder Structs in einzelne benannte Variablen in einer einzigen Deklaration.
Die grundlegende Syntax verwendet auto mit eckigen Klammern:
auto [var1, var2, ...] = composite_object;Entpacken eines std::pair:
std::pair<std::string, int> person{"Alice", 25};
auto [name, age] = person;Entpacken eines std::tuple:
std::tuple<int, double, char> data{42, 3.14, 'X'};
auto [num, pi, letter] = data;Verwendung von Structured Bindings in bereichsbasierten for-Schleifen mit Containern wie std::map:
std::map<std::string, int> scores{{"Bob", 90}, {"Carol", 85}};
for (const auto& [student, score] : scores) {
std::cout << student << ": " << score << "\n";
}Entpacken von Structs mit öffentlichen Membern:
struct Point {
double x;
double y;
};
Point getOrigin() { return {0.0, 0.0}; }
auto [x, y] = getOrigin();Entpacken von Arrays:
int arr[3] = {1, 2, 3};
auto [a, b, c] = arr;Verwenden Sie auto& oder const auto&, um per Referenz zu binden, wodurch Kopien vermieden werden und die Änderung der ursprünglichen Werte ermöglicht wird:
auto& [x, y] = point; // Kann das Original ändern
const auto& [name, age] = person; // Schreibgeschützte ReferenzProbier es selbst
#include <iostream>
#include <string>
#include "Student.h"
#include "GradeUtils.h"
int main() {
// Eingaben lesen
std::string studentName;
int studentId;
std::string courseName;
int score;
std::cin >> studentName;
std::cin >> studentId;
std::cin >> courseName;
std::cin >> score;
// TODO: createStudent mit name, id und einem Platzhalter-GPA von 0.0 aufrufen
// Structured Bindings verwenden, um das struct zu entpacken: auto [name, id, gpa] = ...
// Ausgeben: Student: [name] (ID: [id])
// TODO: makeScorePair mit Kursname und score aufrufen
// Structured Bindings verwenden, um das pair zu entpacken: auto [course, sc] = ...
// Ausgeben: Course: [course], Score: [score]
// TODO: getGradeInfo mit dem score aufrufen
// Structured Bindings verwenden, um das tuple zu entpacken: auto [letter, points, passing] = ...
// Ausgeben:
// Grade: [letter]
// Points: [points]
// Passing: [yes/no] ("yes" ausgeben, wenn passing true ist, "no" wenn false)
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamensräume & GültigkeitsbereicheEinführung in OOP in C++Klassen vs. ObjekteDer 'this'-PointerMethoden (Elementfunktionen)Attribute (Datenelemente)Grundlagen zu Ctors & DtorsRückblick - Einfacher Taschenrechner4Klasseneigenschaften
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen & KlassenZusammenfassung - Bankkonto-Manager7Vererbung
Grundlagen der VererbungZugriffsstufen bei VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick - Mitarbeiter-Hierarchie2Speicherverwaltung
Stack vs. Heap SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Smart Pointers in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsspezifizierer in C++Zugriffsspezifizierer im DetailInformation HidingStruct vs. ClassVerschachtelte & innere KlassenRückblick - Studentenverwaltungssystem8Polymorphie
Kompilierzeit- vs. Laufzeit-PolymorphieFunktionsüberladungVirtuelle Funktionen – WiederholungRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIZusammenfassung – Formen-Rechner3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorVerschiebekonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktoren im DetailRule of Three / Five / ZeroZusammenfassung - String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladen der [] und () OperatorenTypumwandlungsoperatorenRückblick - Matrix-Klasse9Templates
FunktionstemplatesKlassentemplatesTemplate-SpezialisierungVariadische TemplatesSFINAE & Type Traits GrundlagenRückblick - Generische Container12Moderne C++ Features
Move-Semantik & RvaluesPerfect ForwardingLambda-Ausdrücke im Detailstd::function & std::bindconstexpr und constevalStructured Bindingsoptional, variant, any