c++ standards c++17 decltype structured-bindings

c++ - ¿Por qué "const auto[x, y]" no se comporta como se espera cuando se vincula a tipos de referencia?



standards c++17 (2)

El siguiente fragmento de código está extraído de cppref :

std::tuple<int, int&> f(); auto [x, y] = f(); // decltype(x) is int // decltype(y) is int& const auto [z, w] = f(); // decltype(z) is const int // decltype(w) is int&

Mi pregunta está en la última línea:

¿Por qué es decltype(w) int& lugar de const int& ?


Sería la referencia en sí misma en lugar del valor referenciado que sería constante. Como las referencias no son modificables de todos modos, no hay tal cosa como una referencia constante.


Jarod42 respondió la pregunta, la pregunta en los comentarios, permítanme citar la parte relevante de la norma aquí, de [dcl.struct.bind]:

Dado el tipo Ti designado por std :: tuple_element :: type, las variables se introducen con nombres únicos ri de tipo "referencia a Ti" inicializadas con el inicializador ([dcl.init.ref]), donde la referencia es una referencia lvalue si el inicializador es un lvalue y una referencia rvalue de lo contrario. Cada vi es el nombre de un lvalor de tipo Ti que hace referencia al objeto vinculado a ri; el tipo de referencia es Ti.

Por lo tanto, en const auto [z, w] = f(); , tiene const T1 con T1 siendo int y const T2 con T2 siendo int& . A medida que const modifica lo que está a su izquierda, esto se convierte en int& const y da como resultado int& .

Tenga en cuenta que int& const convierte en int& solo es posible en la sustitución de argumentos de plantilla, es decir, esto no compilará:

int n = 42; int& const doesntWork = n; // Error: ''const'' qualifiers cannot be applied to ''int&''

pero esto hace:

template <class T> void f(const T t) { ++t; } int n = 42; f<int&>(n);

donde tiene lugar la contracción idéntica de int& const a int& as anterior.

¹ Gracias a @cpplearner por indicarme el párrafo exacto aquí.