Menu
Coddy logo textTech

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.

challenge icon

Défi

Facile

Construisons 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 structure Student avec 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ée createStudent qui prend un nom, un identifiant et un GPA, et retourne une structure Student.
  • GradeUtils.h : Créez des fonctions utilitaires pour le traitement des notes.

    Définissez une fonction getGradeInfo qui prend un score numérique (entier) et retourne un std::tuple contenant 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 makeScorePair qui prend un nom de cours (std::string) et un score (int), retournant une std::pair de ces valeurs.

  • main.cpp : Lisez quatre entrées :
    1. Nom de l'étudiant (chaîne de caractères)
    2. Identifiant de l'étudiant (entier)
    3. Nom du cours (chaîne de caractères)
    4. Score (entier)

    Utilisez des liaisons structurées tout au long de votre fonction principale :

    1. Appelez createStudent avec 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])
    2. Appelez makeScorePair avec le nom du cours et le score. Utilisez des liaisons structurées pour déballer la paire, puis affichez : Course: [course], Score: [score]
    3. Appelez getGradeInfo avec le score. Utilisez des liaisons structurées pour déballer les trois éléments du tuple, puis affichez :
      Grade: [letter]
      Points: [points]
      Passing: [yes/no]
      (Affichez "yes" si passing est vrai, "no" si faux)

Par exemple, avec les entrées Alice, 1001, Math, et 85 :

Student: Alice (ID: 1001)
Course: Math, Score: 85
Grade: B
Points: 3
Passing: yes

Avec les entrées Bob, 2002, Physics, et 55 :

Student: Bob (ID: 2002)
Course: Physics, Score: 55
Grade: F
Points: 0
Passing: no

N'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 seule

Essayez 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;
}
quiz iconTestez-vous

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