Vinculações Estruturadas
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 88 de 104.
Bindings estruturados, introduzidos no C++17, permitem descompactar vários valores de arrays, pares, tuplas 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 um tuple
std::tuple<int, double, char> data{42, 3.14, 'X'};
auto [num, pi, letter] = data;
// Desempacotando em laços 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";
}
}As vinculações estruturadas também funcionam com arrays e structs personalizados que têm 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. Esse recurso é especialmente útil ao iterar sobre contêineres da STL ou ao lidar com funções que retornam vários valores.
Desafio
FácilVamos criar um analisador de notas de alunos que demonstra o poder das vinculações estruturadas. Você criará um sistema que processa registros de alunos e dados de cursos, usando vinculações estruturadas para desempacotar pares, tuplas e structs de forma elegante ao longo do 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). Crie também uma função chamadacreateStudentque receba um nome, um ID e um GPA, e retorne uma structStudent.GradeUtils.h: Crie funções utilitárias para o processamento de notas.Defina uma função
getGradeInfoque receba uma pontuação numérica (inteiro) e retorne umstd::tuplecontendo três valores: a nota em letra (std::string), os pontos da nota (double) e se houve aprovação (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
Defina também uma função
makeScorePairque receba o nome de um curso (std::string) e a 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 vinculações estruturadas ao longo da sua função principal:
- Chame
createStudentcom o nome, o ID e um GPA de espaço reservado igual a 0.0. Use vinculações estruturadas 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 vinculações estruturadas para desempacotar o par e, em seguida, imprima:Course: [course], Score: [score] - Chame
getGradeInfocom a pontuação. Use vinculações estruturadas para desempacotar os três elementos da tupla e, em seguida, imprima:(Imprima "yes" se passing for true e "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 e 55:
Student: Bob (ID: 2002)
Course: Physics, Score: 55
Grade: F
Points: 0
Passing: noLembre-se de incluir <tuple> e <utility> quando necessário. A principal ideia é entender como as vinculações estruturadas permitem desempacotar tipos compostos, pares, tuplas e structs em variáveis nomeadas em uma única declaração legível.
Experimente você mesmo
#include <iostream>
#include <string>
#include "Student.h"
#include "GradeUtils.h"
int main() {
// Ler entradas
std::string studentName;
int studentId;
std::string courseName;
int score;
std::cin >> studentName;
std::cin >> studentId;
std::cin >> courseName;
std::cin >> score;
// TODO: Chame createStudent com name, id e GPA placeholder de 0.0
// Use structured bindings para desempacotar a struct: auto [name, id, gpa] = ...
// Imprima: Student: [name] (ID: [id])
// TODO: Chame makeScorePair com o nome do curso e score
// Use structured bindings para desempacotar o pair: auto [course, sc] = ...
// Imprima: Course: [course], Score: [score]
// TODO: Chame getGradeInfo com o score
// Use structured bindings para desempacotar a tuple: auto [letter, points, passing] = ...
// Imprima:
// Grade: [letter]
// Points: [points]
// Passing: [yes/no] (imprima "yes" se passing for true, "no" se 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 POO
Arquivos externosBuild e compilação em C++Arquivos de cabeçalho e arquivos-fonteNamespaces e escopoIntrodução à POO em C++Classes vs. objetosO ponteiro 'this'Métodos (funções membro)Atributos (membros de dados)Noções básicas de construtores e destruidoresRevisão - calculadora simples4Propriedades de Classe
Membros de Instância vs. EstáticosGetters e SettersFunções Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRevisão - Gerenciador de Contas Bancárias7Herança
Herança básicaNíveis de acesso da herançaOrdem de chamada de construtor e destrutorSobrescrita de métodosFunções virtuais e VTableHerança múltiplaHerança virtualRevisão - Hierarquia de funcionários10Visão geral da STL
Visão geral e filosofia da STLContêineres da STLIteradoresAlgoritmos da STLFunctors e expressões lambdaRecapitulação - Frequência de palavras13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonFactory e Abstract FactoryPadrão BuilderPadrão ObserverPadrão Strategy2Gerenciamento de Memória
Memória Stack vs. HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Ponteiros Inteligentes em C++RAII em C++Revisão - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de acesso em C++Especificadores de acesso em profundidadeOcultação de informaçõesStruct vs ClasseClasses aninhadas e internasRecapitulação - Sistema de registros de alunos8Polimorfismo
Polimorfismo em compilação vs. execuçãoSobrecarga de funçõesFunções virtuais revisadasFunções virtuais purasClasses abstratasDesign de interfaces em C++Conversão dinâmica e RTTIRecapitulação — Calculadora de formas11Conceitos Avançados de OOP
Composição vs. HerançaMixins via CRTPIdioma PimplApagamento de TiposClasses Enum e Tipagem ForteTratamento de Exceções em OOPHierarquias de Exceções Personalizadas14Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositeRAII como Padrão3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentoListas de Inicialização do ConstrutorConstrutores DelegantesAprofundamento em DestrutoresRegra dos Três / Cinco / ZeroRevisão - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de FluxoSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçõesTemplates de ClassesEspecialização de TemplatesTemplates VariádicosNoções Básicas de SFINAE e Traits de TiposRecapitulação - Contêiner Genérico12Recursos Modernos do C++
Semântica de Movimentação e RvaluesEncaminhamento PerfeitoExpressões Lambda em Profundidadestd::function e std::bindconstexpr e constevalVinculações Estruturadasoptional, variant, anyPratique por conta própria: Compilador de C++ online