C++17coreadvanced
Structured Bindings
C++17 · Practical Modern · Compiler flag: -std=c++17
Explanation
Decomposes aggregates (e.g., tuples, structs, arrays) into individually named variables, making it far easier to work with multi-value returns and key-value pairs without verbose `.first`/`.second` or `std::get<>` calls.
Real-World Scenario
Extract position and velocity from a tuple in a physics simulation.
Quick Snippet
snippet.cpp
#include <tuple>
#include <map>
auto [x, y] = std::make_tuple(3.14, 2.71);
std::map<std::string, int> scores = {{"Alice", 95}, {"Bob", 87}};
for (const auto& [name, score] : scores) {
std::cout << name << ": " << score << "\n";
}Full Example
structured_bindings.cpp
// CodeNebula - C++17 Example: Structured Bindings
// Compile: g++ -std=c++17 -Wall -Wextra -o example structured_bindings.cpp
// Demonstrates structured bindings (auto [a, b] = ...) which allow unpacking
// pairs, tuples, structs, and arrays into named variables in a single declaration.
#include <iostream>
#include <tuple>
#include <map>
#include <string>
struct Point {
double x;
double y;
double z;
};
std::tuple<int, std::string, bool> get_record() {
return {42, "Alice", true};
}
int main()
{
// ------------------------------------------------------------------
// 1. Binding from std::pair
// ------------------------------------------------------------------
std::pair<int, std::string> p{1, "hello"};
auto [id, name] = p;
std::cout << "=== std::pair ===" << std::endl;
std::cout << " id: " << id << ", name: " << name << std::endl;
// ------------------------------------------------------------------
// 2. Binding from std::tuple
// ------------------------------------------------------------------
auto [num, who, active] = get_record();
std::cout << "\n=== std::tuple ===" << std::endl;
std::cout << " num: " << num << ", who: " << who
<< ", active: " << std::boolalpha << active << std::endl;
// ------------------------------------------------------------------
// 3. Binding from a struct (public members, in declaration order)
// ------------------------------------------------------------------
Point pt{1.5, 2.7, 3.9};
auto [px, py, pz] = pt;
std::cout << "\n=== struct ===" << std::endl;
std::cout << " x: " << px << ", y: " << py << ", z: " << pz << std::endl;
// ------------------------------------------------------------------
// 4. Binding from a C-style array
// ------------------------------------------------------------------
int arr[3] = {10, 20, 30};
auto [a, b, c] = arr;
std::cout << "\n=== array ===" << std::endl;
std::cout << " a: " << a << ", b: " << b << ", c: " << c << std::endl;
// ------------------------------------------------------------------
// 5. Binding by reference (modifications affect the original)
// ------------------------------------------------------------------
auto& [rx, ry, rz] = pt;
rx = 100.0;
std::cout << "\n=== reference binding ===" << std::endl;
std::cout << " pt.x after modification: " << pt.x << std::endl;
// ------------------------------------------------------------------
// 6. Using structured bindings in range-for with std::map
// ------------------------------------------------------------------
std::map<std::string, int> scores{{"Alice", 95}, {"Bob", 87}, {"Carol", 92}};
std::cout << "\n=== map iteration ===" << std::endl;
for (const auto& [student, score] : scores) {
std::cout << " " << student << ": " << score << std::endl;
}
return 0;
}
/*
Expected output:
=== std::pair ===
id: 1, name: hello
=== std::tuple ===
num: 42, who: Alice, active: true
=== struct ===
x: 1.5, y: 2.7, z: 3.9
=== array ===
a: 10, b: 20, c: 30
=== reference binding ===
pt.x after modification: 100
=== map iteration ===
Alice: 95
Bob: 87
Carol: 92
*/
Run command
g++ -std=c++17 -Wall -Wextra -o example structured_bindings.cpp