Ответ 1
Jarod42 ответил на вопрос в комментариях, позвольте мне просто привести соответствующую часть стандарта здесь, из [dcl.struct.bind] ¹:
Учитывая тип Ti, обозначенный типом std :: tuple_element ::, вводятся переменные с уникальными именами ri типа "ссылка на Ti", инициализированным инициализатором ([dcl.init.ref]), где ссылка ссылка lvalue, если инициализатор является значением lvalue и ссылкой rvalue в противном случае. Каждое vi является именем lvalue типа Ti, которое ссылается на объект, связанный с ri; ссылочным типом является Ti.
Следовательно, в const auto [z, w] = f();
, у вас есть const T1
где T1
есть int
и const T2
а T2
- int&
. Поскольку const
изменяет то, что слева от него, это становится int& const
и приводит к int&
.
Обратите внимание, что int& const
становится int&
возможно только при замене аргумента шаблона, т.е. Это не будет компилироваться:
int n = 42;
int& const doesntWork = n; // Error: 'const' qualifiers cannot be applied to 'int&'
но это делает:
template <class T> void f(const T t)
{
++t;
}
int n = 42;
f<int&>(n);
где происходит идентичное сокращение от int& const
до int&
как указано выше.
¹ Спасибо @cpplearner за то, что вы указали мне точный параграф.