Structured Bindings
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 88 de 104.
Structured bindings, introduzidas no C++17, permitem desempacotar múltiplos valores de arrays, pairs, tuples ou structs em variáveis nomeadas individuais em uma única declaração. Isso torna o código mais limpo e legível ao trabalhar com dados compostos.
A sintaxe usa auto com colchetes contendo os novos nomes de variáveis:
#include <iostream>
#include <map>
#include <tuple>
int main() {
// Desempacotando um pair
std::pair<std::string, int> person{"Alice", 25};
auto [name, age] = person;
std::cout << name << " is " << age << "\n";
// Desempacotando uma tupla
std::tuple<int, double, char> data{42, 3.14, 'X'};
auto [num, pi, letter] = data;
// Desempacotando em loops for baseados em intervalo
std::map<std::string, int> scores{{"Bob", 90}, {"Carol", 85}};
for (const auto& [student, score] : scores) {
std::cout << student << ": " << score << "\n";
}
}Structured bindings também funcionam com arrays e structs personalizadas que possuem membros públicos:
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;
}Você pode usar auto& ou const auto& para vincular por referência, evitando cópias e permitindo a modificação dos valores originais quando necessário. Este recurso é especialmente útil ao iterar sobre containers STL ou ao lidar com funções que retornam múltiplos valores.
Desafio
FácilVamos construir um analisador de notas de alunos que demonstra o poder dos structured bindings. Você criará um sistema que processa registros de alunos e dados de cursos, usando structured bindings para desempacotar elegantemente pairs, tuples e structs em todo o seu código.
Você organizará seu código em três arquivos:
Student.h: Defina uma structStudentcom membros públicos para o nome do aluno (std::string), ID (int) e GPA (double). Também crie uma função chamadacreateStudentque recebe um nome, ID e GPA, e retorna uma structStudent.GradeUtils.h: Crie funções utilitárias para o processamento de notas.Defina uma função
getGradeInfoque recebe uma pontuação numérica (inteiro) e retorna umstd::tuplecontendo três valores: a nota em letra (std::string), os pontos da nota (double) e se foi aprovado (bool). Use esta escala de notas:- 90+ : "A", 4.0, true
- 80-89: "B", 3.0, true
- 70-79: "C", 2.0, true
- 60-69: "D", 1.0, true
- Abaixo de 60: "F", 0.0, false
Também defina uma função
makeScorePairque recebe um nome de curso (std::string) e uma pontuação (int), retornando umstd::pairdesses valores.main.cpp: Leia quatro entradas:- Nome do aluno (string)
- ID do aluno (inteiro)
- Nome do curso (string)
- Pontuação (inteiro)
Use structured bindings em toda a sua função main:
- Chame
createStudentcom o nome, ID e um GPA de espaço reservado de 0.0. Use structured bindings para desempacotar a struct retornada em variáveis individuais e, em seguida, imprima:Student: [name] (ID: [id]) - Chame
makeScorePaircom o nome do curso e a pontuação. Use structured bindings para desempacotar o pair e, em seguida, imprima:Course: [course], Score: [score] - Chame
getGradeInfocom a pontuação. Use structured bindings para desempacotar todos os três elementos da tupla e, em seguida, imprima:(Imprima "yes" se passing for true, "no" se for false)Grade: [letter] Points: [points] Passing: [yes/no]
Por exemplo, com as entradas Alice, 1001, Math e 85:
Student: Alice (ID: 1001)
Course: Math, Score: 85
Grade: B
Points: 3
Passing: yesCom as entradas Bob, 2002, Physics, and 55:
Student: Bob (ID: 2002)
Course: Physics, Score: 55
Grade: F
Points: 0
Passing: noLembre-se de incluir <tuple> e <utility> onde for necessário. O ponto principal é como os structured bindings permitem desempacotar tipos compostos — pairs, tuples e structs — em variáveis nomeadas em uma única declaração legível.
Folha de consulta
Structured bindings (C++17) permitem desempacotar múltiplos valores de arrays, pairs, tuples ou structs em variáveis nomeadas individuais em uma única declaração.
A sintaxe básica utiliza auto com colchetes:
auto [var1, var2, ...] = composite_object;Desempacotando um std::pair:
std::pair<std::string, int> person{"Alice", 25};
auto [name, age] = person;Desempacotando um std::tuple:
std::tuple<int, double, char> data{42, 3.14, 'X'};
auto [num, pi, letter] = data;Usando structured bindings em loops for baseados em intervalo (range-based for loops) com containers como std::map:
std::map<std::string, int> scores{{"Bob", 90}, {"Carol", 85}};
for (const auto& [student, score] : scores) {
std::cout << student << ": " << score << "\n";
}Desempacotando structs com membros públicos:
struct Point {
double x;
double y;
};
Point getOrigin() { return {0.0, 0.0}; }
auto [x, y] = getOrigin();Desempacotando arrays:
int arr[3] = {1, 2, 3};
auto [a, b, c] = arr;Use auto& ou const auto& para vincular por referência, evitando cópias e permitindo a modificação dos valores originais:
auto& [x, y] = point; // Pode modificar o original
const auto& [name, age] = person; // Referência apenas de leituraExperimente você mesmo
#include <iostream>
#include <string>
#include "Student.h"
#include "GradeUtils.h"
int main() {
// Ler as entradas
std::string studentName;
int studentId;
std::string courseName;
int score;
std::cin >> studentName;
std::cin >> studentId;
std::cin >> courseName;
std::cin >> score;
// TODO: Chamar createStudent com name, id e um GPA reservado de 0.0
// Usar structured bindings para desempacotar a struct: auto [name, id, gpa] = ...
// Imprimir: Student: [name] (ID: [id])
// TODO: Chamar makeScorePair com course name e score
// Usar structured bindings para desempacotar o pair: auto [course, sc] = ...
// Imprimir: Course: [course], Score: [score]
// TODO: Chamar getGradeInfo com o score
// Usar structured bindings para desempacotar a tuple: auto [letter, points, passing] = ...
// Imprimir:
// Grade: [letter]
// Points: [points]
// Passing: [yes/no] (imprimir "yes" se passing for true, "no" se for false)
return 0;
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP
Arquivos ExternosBuild e Compilação em C++Arquivos Header e SourceNamespaces e EscopoIntrodução a OOP em C++Classes vs ObjetosO Ponteiro 'this'Métodos (Funções Membro)Atributos (Membros de Dados)Básico de Ctors e DtorsRecapitulação - Calculadora Simples4Propriedades de Classe
Membros de Instância vs EstáticosGetters e SettersFunções de Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRecapitulação - Gerenciador de Conta Bancária7Herança
Herança BásicaNíveis de Acesso na HerançaOrdem de Chamada de Ctor e DtorSobrescrita de MétodosFunções Virtuais e VTableHerança MúltiplaHerança VirtualRecapitulação - Hierarquia de Funcionários2Gerenciamento de Memória
Memória Stack vs HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Smart Pointers em C++RAII em C++Recapitulação - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de Acesso em C++Especificadores de Acesso em DetalhesOcultação de InformaçãoStruct vs ClassClasses Aninhadas e InternasRecapitulação - Sistema de Registros de Alunos8Polimorfismo
Polimorfismo de Compilação vs Tempo de ExecuçãoSobrecarga de FunçõesFunções Virtuais RevisitadasFunções Virtuais PurasClasses AbstratasDesign de Interfaces em C++Dynamic Casting e RTTIRecapitulação - Calculadora de Formas3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentaçãoListas de Inicialização do ConstrutorConstrutores DelegadosMergulho Profundo em DestrutoresRegra dos Três / Cinco / ZeroRecapitulação - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de StreamSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçãoTemplates de ClasseEspecialização de TemplatesTemplates VariádicosFundamentos de SFINAE e Type TraitsRecapitulação - Container Genérico12Recursos do C++ Moderno
Semântica de Movimento e RvaluesPerfect ForwardingExpressões Lambda em Detalhesstd::function & std::bindconstexpr e constevalStructured Bindingsoptional, variant, any