Liaisons structurées
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy — leçon 88 sur 104.
Les liaisons structurées (structured bindings), introduites en C++17, vous permettent de déballer plusieurs valeurs à partir de tableaux, de paires, de tuples ou de structures dans des variables nommées individuelles en une seule déclaration. Cela rend le code plus propre et plus lisible lorsque vous travaillez avec des données composites.
La syntaxe utilise auto avec des crochets contenant les nouveaux noms de variables :
#include <iostream>
#include <map>
#include <tuple>
int main() {
// Déballage d'une paire (pair)
std::pair<std::string, int> person{"Alice", 25};
auto [name, age] = person;
std::cout << name << " is " << age << "\n";
// Déballage d'un tuple
std::tuple<int, double, char> data{42, 3.14, 'X'};
auto [num, pi, letter] = data;
// Déballage dans des boucles for basées sur une plage (range-based for loops)
std::map<std::string, int> scores{{"Bob", 90}, {"Carol", 85}};
for (const auto& [student, score] : scores) {
std::cout << student << ": " << score << "\n";
}
}Les liaisons structurées fonctionnent également avec les tableaux et les structures personnalisées qui ont des membres publics :
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;
}Vous pouvez utiliser auto& ou const auto& pour lier par référence, en évitant les copies et en permettant la modification des valeurs d'origine si nécessaire. Cette fonctionnalité est particulièrement utile lors de l'itération sur des conteneurs STL ou lors de la manipulation de fonctions qui retournent plusieurs valeurs.
Défi
FacileConstruisons un analyseur de notes d'étudiants qui met en avant la puissance des liaisons structurées (structured bindings). Vous allez créer un système qui traite les dossiers des étudiants et les données des cours, en utilisant des liaisons structurées pour déballer élégamment des paires, des tuples et des structures tout au long de votre code.
Vous organiserez votre code sur trois fichiers :
Student.h: Définissez une structureStudentavec des membres publics pour le nom de l'étudiant (std::string), son identifiant (int) et sa moyenne GPA (double). Créez également une fonction appeléecreateStudentqui prend un nom, un identifiant et un GPA, et retourne une structureStudent.GradeUtils.h: Créez des fonctions utilitaires pour le traitement des notes.Définissez une fonction
getGradeInfoqui prend un score numérique (entier) et retourne unstd::tuplecontenant trois valeurs : la lettre de la note (std::string), les points de grade (double) et si la note est validée (bool). Utilisez ce barème de notation :- 90+ : "A", 4.0, true
- 80-89: "B", 3.0, true
- 70-79: "C", 2.0, true
- 60-69: "D", 1.0, true
- Moins de 60 : "F", 0.0, false
Définissez également une fonction
makeScorePairqui prend un nom de cours (std::string) et un score (int), retournant unestd::pairde ces valeurs.main.cpp: Lisez quatre entrées :- Nom de l'étudiant (chaîne de caractères)
- Identifiant de l'étudiant (entier)
- Nom du cours (chaîne de caractères)
- Score (entier)
Utilisez des liaisons structurées tout au long de votre fonction principale :
- Appelez
createStudentavec le nom, l'identifiant et un GPA fictif de 0.0. Utilisez des liaisons structurées pour déballer la structure retournée dans des variables individuelles, puis affichez :Student: [name] (ID: [id]) - Appelez
makeScorePairavec le nom du cours et le score. Utilisez des liaisons structurées pour déballer la paire, puis affichez :Course: [course], Score: [score] - Appelez
getGradeInfoavec le score. Utilisez des liaisons structurées pour déballer les trois éléments du tuple, puis affichez :(Affichez "yes" si passing est vrai, "no" si faux)Grade: [letter] Points: [points] Passing: [yes/no]
Par exemple, avec les entrées Alice, 1001, Math, et 85 :
Student: Alice (ID: 1001)
Course: Math, Score: 85
Grade: B
Points: 3
Passing: yesAvec les entrées Bob, 2002, Physics, et 55 :
Student: Bob (ID: 2002)
Course: Physics, Score: 55
Grade: F
Points: 0
Passing: noN'oubliez pas d'inclure <tuple> et <utility> là où c'est nécessaire. L'idée clé est de voir comment les liaisons structurées vous permettent de déballer des types composites — paires, tuples et structures — dans des variables nommées en une seule déclaration lisible.
Aide-mémoire
Les liaisons structurées (C++17) permettent de déballer plusieurs valeurs à partir de tableaux, de paires, de tuples ou de structures dans des variables nommées individuelles en une seule déclaration.
La syntaxe de base utilise auto avec des crochets :
auto [var1, var2, ...] = composite_object;Déballage d'une std::pair :
std::pair<std::string, int> person{"Alice", 25};
auto [name, age] = person;Déballage d'un std::tuple :
std::tuple<int, double, char> data{42, 3.14, 'X'};
auto [num, pi, letter] = data;Utilisation des liaisons structurées dans les boucles for basées sur une plage avec des conteneurs comme std::map :
std::map<std::string, int> scores{{"Bob", 90}, {"Carol", 85}};
for (const auto& [student, score] : scores) {
std::cout << student << ": " << score << "\n";
}Déballage de structures avec des membres publics :
struct Point {
double x;
double y;
};
Point getOrigin() { return {0.0, 0.0}; }
auto [x, y] = getOrigin();Déballage de tableaux :
int arr[3] = {1, 2, 3};
auto [a, b, c] = arr;Utilisez auto& ou const auto& pour lier par référence, évitant ainsi les copies et permettant la modification des valeurs d'origine :
auto& [x, y] = point; // Peut modifier l'original
const auto& [name, age] = person; // Référence en lecture seuleEssayez vous-même
#include <iostream>
#include <string>
#include "Student.h"
#include "GradeUtils.h"
int main() {
// Lire les entrées
std::string studentName;
int studentId;
std::string courseName;
int score;
std::cin >> studentName;
std::cin >> studentId;
std::cin >> courseName;
std::cin >> score;
// TODO: Appeler createStudent avec name, id, et un GPA fictif de 0.0
// Utiliser les structured bindings pour déballer la struct : auto [name, id, gpa] = ...
// Afficher : Student: [name] (ID: [id])
// TODO: Appeler makeScorePair avec le nom du cours et le score
// Utiliser les structured bindings pour déballer la paire : auto [course, sc] = ...
// Afficher : Course: [course], Score: [score]
// TODO: Appeler getGradeInfo avec le score
// Utiliser les structured bindings pour déballer le tuple : auto [letter, points, passing] = ...
// Afficher :
// Grade: [letter]
// Points: [points]
// Passing: [yes/no] (afficher "yes" si passing est vrai, "no" si faux)
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesBuild et Compilation C++Fichiers d'en-tête et Fichiers sourceEspaces de noms et PortéeIntroduction à la POO en C++Classes vs ObjetsLe pointeur 'this'Méthodes (Fonctions membres)Attributs (Membres de données)Bases des Ctors et DtorsRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d'instance vs membres statiquesGetters et SettersFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d'accès à l'héritageOrdre d'appel des Ctor et DtorRedéfinition de méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif - Hiérarchie des employés10Présentation de la STL
Présentation et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - Fréquence des mots13Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonFabrique & Fabrique abstraitePatron MonteurPatron ObservateurPatron Stratégie2Gestion de la mémoire
Mémoire Pile vs TasPointeurs et RéférencesMémoire dynamique (new/delete)Smart Pointers en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d'accès en C++Spécificateurs d'accès en profondeurMasquage d'informationStruct vs ClassClasses imbriquées et internesRécapitulatif - Système de gestion d'étudiants8Polymorphisme
Polymorphisme : Compilation vs ExécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d'interfaces en C++Dynamic Casting & RTTIRécapitulatif - Calculateur de formes11Concepts avancés de la POO
Composition vs HéritageMixins via CRTPIdiome PimplEffacement de typeEnum Classes & Typage fortGestion des exceptions en POOHiérarchies d'exceptions personnalisées14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeRAII en tant que patron3Constructeurs et Destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d'initialisation du constructeurConstructeurs déléguésAnalyse approfondie du destructeurRègle de trois / cinq / zéroRécapitulatif - Classe String6Surcharge d'opérateurs
Introduction à la surcharge d'opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l'opérateur d'affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif - Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation de templatesTemplates variadiquesBases de SFINAE & Type TraitsRécapitulatif - Conteneur générique12Fonctionnalités du C++ moderne
Sémantique de mouvement et RvaluesTransfert parfaitExpressions Lambda en profondeurstd::function et std::bindconstexpr et constevalLiaisons structuréesoptional, variant, any