valores retornan referencias referencia que por pasos paso parametros parametro para funciones ejercicios ejemplos como asignar arreglos c++ c++11 language-lawyer trailing-return-type

c++ - retornan - ¿Se puede usar el valor del parámetro directamente(no su tipo sino el valor mismo) en la sintaxis del tipo de retorno final?



pasos para asignar un parametro en c++ (2)

Creo que tus dos ejemplos están equivocados. Basado en el texto estándar 5.20 Expresiones constantes [expr.const] /p2.7 :

2 Una expresión condicional e es una expresión constante central a menos que la evaluación de e, siguiendo las reglas de la máquina abstracta (1.9), evalúe una de las siguientes expresiones: j

...

- una conversión de lvalue a rvalue (4.1) a menos que se aplique a:

Los parámetros de función no pueden ser expresiones constantes, ya que para pasarlos como parámetros de plantilla, está aplicando la conversión de lvalue a rvalue en ellos.

Tanto en CLANG como en GCC, si insiste en las plantillas, obtendrá un error basado en el texto anterior. Creo que ya que en los ejemplos no se insinúa la plantilla, no se requiere ningún diagnóstico, por lo que ambos compiladores son correctos.

Considere el ejemplo mínimo:

template <int> struct bar { }; int main() { [](auto i) -> bar<i> { return {}; }; }

O incluso:

template <int> struct bar {}; template <class I> auto foo(I i) -> bar<i> {}

clang compila ambas formas sin problemas pero gcc encuentra los usos no válidos (ej. 1) , (ej. 2)

La pregunta puede parecer tonta, sin embargo, el tipo de parámetro puede tener el operador de conversión constexpr sobrecargado (en este caso, el tipo de i deducido del valor pasado a lambda / foo a int de manera constante) y en este escenario sería bastante conveniente no serlo. Obligado a hacer algunas soluciones para acceder directamente ...


Esto parece un error de gcc . Lo reporté como problema #80242 .

gcc queja de la validez de i como argumento de plantilla:

error : el argumento de la plantilla 1 no es válido

He seguido la gramática de C ++ desde trailing-return-type hasta template-argument , que debe ser una constant-expression :

argumento de la plantilla :

  • expresión constante <-
  • tipo-id
  • id-expresión

La verdadera pregunta entonces es: "¿ i una constant-expression válida?" .

Creo que la respuesta es "sí" , porque §8.20.4 [expr.const] dice:

Una expresión constante convertida de tipo T es una expresión, convertida implícitamente al tipo T , donde la expresión convertida es una expresión constante y la secuencia de conversión implícita contiene solo:

  • conversiones definidas por el usuario,

[...]

(Nota: tales expresiones se pueden usar en nuevas expresiones, como expresiones de casos, como inicializadores del enumerador si el tipo subyacente es fijo, como límites de matriz y como argumentos de plantilla que no son de tipo ).

Hay una secuencia de conversiones implícitas que, a partir de i , producirá una expresión constante convertida que es una expresión constante . Dado:

template <int> struct bar { }; template <class I> auto foo(I i) -> bar<i> { } int main() { foo(std::integral_constant<int, 1>{}); // (0) }

  • En el contexto de la función call en (0) , el argumento i es una instancia de std::integral_constant<int, 1> .

  • std::integral_constant proporciona una constexpr definida por el usuario al value_type subyacente.

  • Las expresiones constantes convertidas permiten explícitamente las conversiones definidas por el usuario , como se ve arriba en §8.20.4 [expr.const] .

  • std::integral_constant::operator value_type() devolverá el argumento de plantilla no tipo 1 . Esta es una expresión constante central, ya que no viola ninguna de las reglas especificadas en §8.20.2 [expr.const] .

  • Por lo tanto, la expresión constante convertida es una expresión constante .