¿Hay alguna manera de deslizar un static_assert en una expresión en ISO C++ 11?
c++11 static-assert (3)
¿Qué pasa con una plantilla de función:
template<int T> void my_static_assert()
{
static_assert(T, "asserted");
}
Luego puede usar el operador de coma, ni siquiera necesita llamar a la función:
int x = (my_static_assert<(2 > 1)>, 2001);
Tal vez necesite algunos paréntesis aquí y allá para hacer feliz al analizador. Y pierdes el mensaje de afirmación estática, pero funciona.
En C ++ 11 es legal escribir, por ejemplo:
int b = (some_function_returning_void(), 1020);
Y obtendrás 1020. Pero no te dejará escribir:
int b = (static_assert(2 > 1, "all is lost"), 304);
La documentation explica los lugares legales donde static_assert (una keyword , aparentemente) puede ocurrir:
Una declaración de afirmación estática puede aparecer en el ámbito del bloque (como una declaración de bloque) y dentro de un cuerpo de clase (como una declaración de miembro)
Solo por el gusto de hacerlo, probé un par de cosas hasta que esto funcionó:
int b = ({static_assert(2 > 1, "all is lost"); 304;});
Pero con -Wpedantic
me sale "warning: ISO C++ forbids braced-groups within expressions"
con -Wpedantic
"warning: ISO C++ forbids braced-groups within expressions"
. Curiosamente, estas se denominan "expresiones de declaración" y se usan en el kernel de Linux .
Pero imaginemos que quiero quedarme -Wpedantic
. ¿Hay soluciones alternativas limpias?
Como @dyp se menciona en los comentarios, puede abusar del operador de coma y una expresión lambda:
([]{static_assert(true,"");}, 42)
static_assert
no es una expresión (a diferencia de sizeof
), por lo que no puede usarla donde se requiera una expresión.
Ni siquiera es una expresión con tipo void
(curiosamente, throw
es una expresión de tipo void
), por lo que ni siquiera se puede usar en forma ternaria.
Las expresiones de los enunciados no son C ++ estándar, por lo que desaconsejo su uso.
Un lambda
int b = []{
static_assert(2 > 1, "all is lost"); return 304;
}();
o
int b = ([]{static_assert(2 > 1, "all is lost");}, 304);
Apenas está limpio. (La segunda lambda parece estar a un pelo de distancia de estar indefinida).