简体   繁体   中英

What are the types of identifiers introduced by structured bindings in C++17?

To my knowledge, identifiers introduced by structured bindings in C++17 are in fact references to some "hidden" variable. Such that

auto [ a, b ] = std::make_tuple(1, 2);

is kind-of equivalent to

auto e = std::make_tuple(1, 2);
auto& a = std::get<0>(e);
auto& b = std::get<1>(e);

However, if I print out std::is_reference<decltype(a)>::value , I get 0 in the first case 1 in the second. Why is that?

if I print out std::is_reference<decltype(a)>::value , I get 0 in the first case 1 in the second.

Why is that even if we can prove that a and b refer to the elements in the tuple and one can modify those values by means of them?
I'm not a language lawyer, but probably it is due to this bullet of the standard (working draft):

if e is an unparenthesized id-expression naming a structured binding [...], decltype(e) is the referenced type as given in the specification of the structured binding declaration


Side note. You should use this form to do so that a and b refer to the elements in the tuple:

auto tup = std::make_tuple(1, 2);
auto & [ a, b ] = tup;

It follows a minimal, working example:

#include <tuple>
#include <type_traits>
#include <iostream>

int main() {
    auto tup = std::make_tuple(1, 2);
    auto & [ a, b ] = tup;
    a = 0;
    std::cout << a << ", " << std::get<0>(tup) << std::endl;
}

See it on Coliru . On the other side, what you get is a copy of the values using the expression below:

auto [ a, b ] = std::make_tuple(1, 2);

Here is an article that explains it better and is a bit more comprehensible than the standard for humans .

To my knowledge, identifiers introduced by structured bindings in C++17 are in fact references to some "hidden" variable.

If by "reference" you mean the language construct reference, this isn't quite correct. The specifiers in the declaration appertain to the "hidden variable" you speak of. The reference qualifier is optional. The code you presented would be more like this:

const auto& e = std::make_tuple(1, 2);
using E = remove_reference_t<decltype((e))>;
std::tuple_element<0, E>::type& a = get<0>(e);
std::tuple_element<1, E>::type& b = get<1>(e);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM