Structured bindings
Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 88 di 104.
I structured bindings, introdotti in C++17, ti permettono di estrarre più valori da array, coppie, tuple o struct e assegnarli a singole variabili con nome in un'unica dichiarazione. Questo rende il codice più pulito e leggibile quando lavori con dati composti.
La sintassi usa auto con parentesi quadre contenenti i nuovi nomi delle variabili:
#include <iostream>
#include <map>
#include <tuple>
int main() {
// Decomposizione di una coppia
std::pair<std::string, int> person{"Alice", 25};
auto [name, age] = person;
std::cout << name << " is " << age << "\n";
// Decomposizione di una tupla
std::tuple<int, double, char> data{42, 3.14, 'X'};
auto [num, pi, letter] = data;
// Decomposizione nei cicli for basati su intervalli
std::map<std::string, int> scores{{"Bob", 90}, {"Carol", 85}};
for (const auto& [student, score] : scores) {
std::cout << student << ": " << score << "\n";
}
}Anche le associazioni strutturate funzionano con gli array e le struct personalizzate che hanno membri pubblici:
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;
}Puoi usare auto& o const auto& per associare per riferimento, evitando copie e consentendo di modificare i valori originali quando necessario. Questa funzionalità è particolarmente utile quando si itera sui contenitori STL o si gestiscono funzioni che restituiscono più valori.
Sfida
FacileCostruiamo un analizzatore dei voti degli studenti che mostri la potenza delle associazioni strutturate. Creerai un sistema che elabora i record degli studenti e i dati dei corsi, usando le associazioni strutturate per decomporre elegantemente coppie, tuple e struct nel tuo codice.
Organizzerai il codice in tre file:
Student.h: Definisci una structStudentcon membri pubblici per il nome dello studente (std::string), l'ID (int) e il GPA (double). Crea anche una funzione chiamatacreateStudentche accetta un nome, un ID e un GPA e restituisce una structStudent.GradeUtils.h: Crea funzioni di utilità per l'elaborazione dei voti.Definisci una funzione
getGradeInfoche accetta un punteggio numerico (intero) e restituisce unastd::tuplecontenente tre valori: il voto in lettere (std::string), i punti del voto (double) e se il risultato è sufficiente (bool). Usa questa scala di valutazione:- 90+ : "A", 4.0, true
- 80-89: "B", 3.0, true
- 70-79: "C", 2.0, true
- 60-69: "D", 1.0, true
- Meno di 60: "F", 0.0, false
Definisci anche una funzione
makeScorePairche accetta il nome di un corso (std::string) e il punteggio (int) e restituisce unastd::paircontenente questi valori.main.cpp: Leggi quattro input:- Nome dello studente (stringa)
- ID dello studente (intero)
- Nome del corso (stringa)
- Punteggio (intero)
Usa le associazioni strutturate in tutta la funzione main:
- Chiama
createStudentcon il nome, l'ID e un GPA segnaposto pari a 0.0. Usa le associazioni strutturate per decomporre la struct restituita in singole variabili, quindi stampa:Student: [name] (ID: [id]) - Chiama
makeScorePaircon il nome del corso e il punteggio. Usa le associazioni strutturate per decomporre la coppia, quindi stampa:Course: [course], Score: [score] - Chiama
getGradeInfocon il punteggio. Usa le associazioni strutturate per decomporre tutti e tre gli elementi della tupla, quindi stampa:(Stampa "yes" se il risultato è sufficiente, "no" se non lo è)Grade: [letter] Points: [points] Passing: [yes/no]
Per esempio, con gli input Alice, 1001, Math e 85:
Student: Alice (ID: 1001)
Course: Math, Score: 85
Grade: B
Points: 3
Passing: yesCon gli input Bob, 2002, Physics e 55:
Student: Bob (ID: 2002)
Course: Physics, Score: 55
Grade: F
Points: 0
Passing: noRicordati di includere <tuple> e <utility> dove necessario. L'idea fondamentale è che le associazioni strutturate ti consentono di decomporre tipi composti, coppie, tuple e struct in variabili denominate con una singola dichiarazione leggibile.
Provalo tu
#include <iostream>
#include <string>
#include "Student.h"
#include "GradeUtils.h"
int main() {
// Leggi gli input
std::string studentName;
int studentId;
std::string courseName;
int score;
std::cin >> studentName;
std::cin >> studentId;
std::cin >> courseName;
std::cin >> score;
// TODO: Chiama createStudent con name, id e un GPA segnaposto di 0.0
// Usa le associazioni strutturate per scomporre la struct: auto [name, id, gpa] = ...
// Stampa: Studente: [name] (ID: [id])
// TODO: Chiama makeScorePair con il nome del corso e il punteggio
// Usa le associazioni strutturate per scomporre la coppia: auto [course, sc] = ...
// Stampa: Corso: [course], Punteggio: [score]
// TODO: Chiama getGradeInfo con il punteggio
// Usa le associazioni strutturate per scomporre la tupla: auto [letter, points, passing] = ...
// Stampa:
// Voto: [letter]
// Punti: [points]
// Promosso: [yes/no] (stampa "yes" se passing è true, "no" se è false)
return 0;
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniBuild e compilazione in C++File header e file sorgenteNamespace e ambitoIntroduzione alla programmazione orientata agli oggetti in C++Classi e oggetti a confrontoIl puntatore 'this'Metodi (funzioni membro)Attributi (membri dati)Fondamenti di costruttori e distruttoriRiepilogo - Calcolatrice semplice4Proprietà delle classi
Membri di istanza e staticiGetter e setterFunzioni membro constParola chiave mutableMetodi e variabili staticiFunzioni e classi friendRiepilogo - Gestore di conti bancari7Ereditarietà
Ereditarietà di baseLivelli di accesso nell’ereditarietàOrdine di chiamata di costruttori e distruttoriRidefinizione dei metodiFunzioni virtuali e VTableEreditarietà multiplaEreditarietà virtualeRiepilogo - Gerarchia dei dipendenti2Gestione della memoria
Memoria Stack vs HeapPuntatori e riferimentiMemoria dinamica (new/delete)Puntatori intelligenti in C++RAII in C++Riepilogo - Gestore di array dinamico5Incapsulamento
Specificatori di accesso in C++Specificatori di accesso in dettaglioOccultamento delle informazioniStruct vs classClassi annidate e interneRiepilogo - Sistema di registrazione degli studenti8Polimorfismo
Polimorfismo a compile time e a runtimeOverload delle funzioniFunzioni virtuali: ripassoFunzioni virtuali pureClassi astratteProgettazione delle interfacce in C++Dynamic casting e RTTIRipasso: calcolatrice di forme11Concetti avanzati di OOP
Composizione vs ereditarietàMixin tramite CRTPIdiom PimplType ErasureEnum class e tipizzazione forteGestione delle eccezioni in OOPGerarchie personalizzate di eccezioni14Pattern di progettazione - Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeRAII come pattern3Costruttori e distruttori
Costruttore predefinitoCostruttore con parametriCostruttore di copiaCostruttore di spostamentoListe di inizializzazione dei costruttoriCostruttori delegantiApprofondimento sui distruttoriRegola del Tre / Cinque / ZeroRipasso - classe String6Sovraccarico degli operatori
Introduzione al sovraccarico degli operatoriSovraccarico degli operatori aritmeticiSovraccarico degli operatori di confrontoOperatori di flussoSovraccarico dell'operatore di assegnazioneSovraccarico degli operatori [] e ()Operatori di conversione di tipoRipasso - Classe Matrix9Template
Template di funzioneTemplate di classeSpecializzazione dei templateTemplate variadiciBasi di SFINAE e dei trait di tipoRiepilogo - Contenitore generico12Funzionalità moderne di C++
Semantica di spostamento e rvaluePerfect forwardingEspressioni lambda in dettagliostd::function e std::bindconstexpr e constevalStructured bindingsoptional, variant, anyEsercitati da solo: Compilatore C++ online