C++ Basics: Choose Copies or References in Structured Bindings
See when editing a tuple binding changes the original record.
Prepare a scratch directory
Tested on Linux x86_64 with GCC 14.2.0. Install a C++20-capable compiler and standard-library development headers, with g++ on PATH. You also need Bash, a text editor, and the mktemp, rm, and rmdir utilities. No third-party library is required.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1Run the example
Save this as structured-bindings-copy-reference-demo.cpp:
#include <iostream>
#include <string>
#include <tuple>
int main()
{
std::tuple<std::string, int> record{"queued", 2};
auto [copied_status, copied_attempts] = record;
copied_status = "local";
++copied_attempts;
std::cout << "Copy: " << copied_status << ' ' << copied_attempts << '\n';
std::cout << "Original: " << std::get<0>(record) << ' ' << std::get<1>(record) << '\n';
auto& [status, attempts] = record;
status = "running";
++attempts;
std::cout << "After reference edit: "
<< std::get<0>(record) << ' ' << std::get<1>(record) << '\n';
}Compile and run it. The program runs only after compilation succeeds:
g++ -std=c++20 -Wall -Wextra -Werror -pedantic structured-bindings-copy-reference-demo.cpp -o structured-bindings-copy-reference-demo &&
./structured-bindings-copy-reference-demoObserved output:
Copy: local 3
Original: queued 2
After reference edit: running 3Read the result
The first declaration creates a hidden tuple copy. Its names refer to the elements of that copy, leaving record unchanged. The second declaration binds the hidden entity by reference, so assignments update the original tuple elements.
Apply it carefully
Use const auto& for read-only access without copying. References must not outlive the tuple they refer to. This example uses a tuple of values: tuples containing references have different aliasing behavior even when the tuple itself is copied. Structured bindings do not make object ownership or lifetime disappear.
The C++ working draft describes the relevant rules. This example uses C++20 facilities; the current working draft also documents later additions.
Clean up
Remove only the source and executable created here, then return to the starting directory:
rm -- structured-bindings-copy-reference-demo.cpp structured-bindings-copy-reference-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directoryIf the directory is not empty, inspect its remaining contents before removing anything else.
Acknowledgements
This post was created with assistance from AI.