Насколько мне известно, идентификаторы, представленные структурированными привязками в 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
во-вторых. Это почему?
если я распечатаю
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);
Вот это статья, которая объясняет это лучше и немного более понятна, чем стандарт для люди.
Насколько мне известно, идентификаторы, представленные структурированными привязками в 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);