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

梦想的初衷 提交于 2019-12-01 14:57:34

问题


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?


回答1:


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.




回答2:


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);


来源:https://stackoverflow.com/questions/44671697/what-are-the-types-of-identifiers-introduced-by-structured-bindings-in-c17

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!