template<typename T>
concept Octet = 1 == sizeof(T);

// ok
Octet decltype(auto) c = 'a';

// ok
void f1(const auto&) {}

// ok
void f2(Octet auto) {}

// ok
void f3(Octet auto&&) {}

// error: expected ‘auto’ or ‘decltype(auto)’ after ‘Octet’
void f4(Octet const auto&) {}

// error: cannot declare a parameter with ‘decltype(auto)’
void f5(Octet decltype(auto)) {}

Compilado con gcc-11 -std=c++20. Ver: https://godbolt.org/z/xK769Pfjn

¿Por qué f4 y f5 no funcionan?

6
xmllmx 7 may. 2021 a las 21:14

1 respuesta

La mejor respuesta

Como se ve en [dcl.spec.auto], cuando Si usa un marcador de posición aquí, la restricción debe preceder inmediatamente a auto:

especificador de tipo de marcador de posición:
tipo-restricción_ opt auto
tipo-restricción_ opt decltype ( auto )

Esto es simplemente una cuestión de sintaxis. La restricción no es un especificador general como lo es const; no tiene una posición flexible. Conceptualmente, puede pensar en Octet auto como una "palabra" que representa el tipo restringido.

En cuanto a f5, esto no está permitido como parámetro por p2:

Un especificador de tipo de marcador de posición con el formato "restricción de tipo_ opt auto "se puede usar como un especificador de decl de la secuencia de especificador de decl de una declaración de parámetro de una declaración de función ...

No existe tal texto para decltype(auto). Además, según p6:

Un programa que utiliza un tipo de marcador de posición en un contexto no permitido explícitamente en esta subcláusula está mal formado.

Lógicamente, no estoy seguro de cómo especificaría decltype(auto) para que funcione en este contexto. Claro, podría especificarse, pero no creo que haya precedentes en el lenguaje para ello, por lo que tendría que estar motivado por una alternativa que ya tenga el efecto deseado.

4
chris 7 may. 2021 a las 18:32