Какие типы идентификаторов введены структурированными привязками в C ++ 17?

Насколько мне известно, идентификаторы, представленные структурированными привязками в C ++ 17, на самом деле являются ссылками на некоторую «скрытую» переменную. Такой, что

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

является вид эквивалентно

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

Тем не менее, если я распечатаю std::is_reference<decltype(a)>::value, Я получил 0 в первом случае 1 во-вторых. Это почему?

9

Решение

если я распечатаю std::is_reference<decltype(a)>::valueЯ получаю 0 в первом случае 1 во втором.

Почему, даже если мы можем доказать это? a а также b обратитесь к элементам в кортеже, и с помощью них можно изменить эти значения?
Я не адвокат по языкам, но, вероятно, это связано с эта пуля стандарта (рабочий проект):

если e это не заключенное в скобки id-выражение, обозначающее структурированную привязку […], decltype(e) ссылочный тип, указанный в спецификации объявления структурированной привязки


Примечание. Вы должны использовать эту форму для того, чтобы a а также b обратитесь к элементам в кортеже:

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

Следует минимальный рабочий пример:

#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;
}

Смотрите это на Coliru. С другой стороны, что вы получаете копия ценностей используя выражение ниже:

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

Вот это статья, которая объясняет это лучше и немного более понятна, чем стандарт для люди.

9

Другие решения

Насколько мне известно, идентификаторы, представленные структурированными привязками в C ++ 17, на самом деле являются ссылками на некоторую «скрытую» переменную.

Если под «ссылкой» вы подразумеваете ссылку на языковую конструкцию, это не совсем правильно. Спецификаторы в объявлении относятся к «скрытой переменной», о которой вы говорите. Ссылочный квалификатор не является обязательным. Код, который вы представили, будет выглядеть примерно так:

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

По вопросам рекламы [email protected]