Uso de lambda en una expresión constante
Toma el siguiente código:
template <typename t,="" typename="" u="">
constexpr bool can_represent(U&& w) noexcept
{
return [] (auto&& x) {
try {
return T(std::forward<u>(x)) == std::forward<u>(x);
} catch(...) {
return false;
}
} (std::forward<u>(w));
}
Estoy usando esta función en una expresión constante (plantilla).
gcc
lo compila sin problemas. clang
y MSVC
no lo hacen, lamentando que la función no resulte en una expresión constante.
De hecho, gcc
tampoco lo aceptó inmediatamente; se estaba colgando en el try
, que normalmente no se permitiría en una función constexpr
. Por eso tuve que usar una expresión lambda invocada inmediatamente. Sin embargo, ahora funciona y considerando que solo funciona con gcc
, estoy bastante confundido.
¿Cuál compilador es el correcto?
¿Hay alguna propiedad de la lambda que permita que esto funcione en un contexto constexpr
, o es alguna extensión no estándar de gcc
?
[He utilizado godbolt para compilar con clang
y MSVC
, mientras que en mi máquina tengo gcc 8.1.0
]
davy.ai
Como modelo de lenguaje de IA, no soy capaz de determinar qué compilador es el correcto, pero puedo proporcionar algunos conocimientos sobre el asunto.
En primer lugar, es importante tener en cuenta que las funciones
constexpr
están destinadas a evaluarse en tiempo de compilación. Sin embargo, algunas características del lenguaje, como las excepciones, no están permitidas en un contextoconstexpr
.En el código proporcionado, la función
constexpr
utiliza una expresión lambda invocada inmediatamente. Encapsula la parte de la función que normalmente causaría una excepción dentro de la función lambda. Luego, la función lambda se llama inmediatamente con el argumentostd::forward<u>(w)
para comprobar si puede representar el tipoT
.Es posible que
gcc
sea capaz de evaluar la función lambda en tiempo de compilación, lo que permitiría que toda la funciónconstexpr
se evalúe en tiempo de compilación. Esto podría explicar por quégcc
puede compilar el código sin problemas, mientras queclang
yMSVC
no pueden.También es posible que este comportamiento sea una extensión no estándar de
gcc
. Sin más información, es difícil determinar qué compilador es el correcto en este caso. Se recomienda consultar la documentación de cada compilador para determinar sus limitaciones y comportamiento específicos con respecto a las funcionesconstexpr
.