c++c++17std-pairstructured-bindings

Can I make one variable from a structured binding const and the other non-const?


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?


Solution

  • 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).