I'd like to be able to decompose a structured binding, of lets say, std::pair<T, U>
into a non-const variable and a const variable:
E.g.
std::pair<int, int> anExamplePair = std::make_pair(1, 2);
auto [nonConstVariable, constVariable] = anExamplePair;
Is this possible or even sensible or do I have to make both variables in the structured binding const or non-const?
into a non-const variable and a const variable:
That's not what a structured binding does at all. The structured binding (implicitly) declares one variable and the auto
or any other type specifiers apply to that variable.
The names given to the structured binding are used as if they named references into the subobjects of that single variable or to the result of a get
call according to the types tuple interface.
These references may or not be const
-qualified. That is not (purely) decided by whether or not you use const
in the structured binding. A type could define its tuple interface so that they are always or never const
-qualified regardless of the const
on the variable itself.
In the case of std::pair
the const
is inherited via std::pair
's tuple interface, so here const
on the variable determines whether both or none of the newly introduced names behave like const
references. It is not possible to add another const
to the type for one of the names. There is no syntax for it.
In particular, given your exact example, the structured binding actually introduces a copy of anExamplePair
and the two names will be referencing the elements in that copy. You should use auto&
instead of auto
if you want references into anExamplePair
.
If you give the pair a name anyway, then there isn't really any point in using a structured binding anyway. You don't gain much versus
std::pair<int, int> anExamplePair = std::make_pair(1, 2);
auto& nonConstVariable = std::get<0>(anExamplePair);
const auto& constVariable = std::get<1>(anExamplePair);
which allows you to give the const
-qualifier explicitly as well.
Structured bindings are just syntactic sugar to avoid having to name the full object (and maybe to avoid writing std::get
explicitly multiple times).