почему структурированные привязки не возвращают ссылки на элементы структуры с помощью `auto&`, но возвращаются сами члены

Я думал, что с помощью структурированных привязок и спецификатора auto& я могу получить ссылки на члены структуры и использовать их напрямую, вместо того, чтобы проходить через структуру.

Однако следующий код работает, и статические утверждения сохраняются:

struct Test
{
    int i;
    char c;
    double d;
};
Test test{ 0, 1, 2 };
auto& [i, c, d] = test;
i = 4;
c = 5;
d = 6;
// i, c, d are not references !
static_assert(!std::is_same_v<decltype(i), int&>);
static_assert(!std::is_same_v<decltype(c), char&>);
static_assert(!std::is_same_v<decltype(d), double&>);
cout << &i << " == " << &test.i << " (" << std::boolalpha << (&i == &test.i) << ")" << endl; // (true)
cout << test.i << ", " << (int)test.c << ", " << test.d << endl; // 4, 5, 6

Но я думал, что С++ не позволяет одной переменной иметь более одного имени, за исключением случаев, когда одно из них является реальной переменной, а другие являются ссылками, но в этом случае переменная i совпадает с test.i, и ни одна из них не является ссылкой.


person dev65    schedule 24.01.2020    source источник
comment
i является ссылкой в ​​коде, который вы показываете. auto& [i ... - Это отсылка.   -  person Jesper Juhl    schedule 24.01.2020
comment
Это разрешает, если две переменные находятся в разных областях.   -  person    schedule 24.01.2020


Ответы (1)


В случае массива и типа структурированные привязки не являются ссылками — они являются псевдонимами соответствующих членов. Основной причиной этого является поддержка битовых полей. У вас не может быть ссылки на битовое поле, но у вас может быть псевдоним:

struct X {
    uint8_t a : 2;
    uint8_t b : 6;
};

void f(X& x) {
    auto& [a, b] = x; // fine, a just means "x.a"
    auto& a2 = x.a;   // error
}

Отдельно от этого decltype() делает что-то специальное для структурированных привязок - он только когда-либо даст вам ссылочный тип, если член привязки refer to является ссылочным типом, например:

struct Y {
    int& a;
    int b;
};

void f(Y& y) {
    auto& [a, b] = y;
    // decltype(a) is int&, decltype(b) is int
}
person Barry    schedule 24.01.2020