static_assert la compilación falla cuando el argumento es un valor constexpr devuelto por una función.
template
constexpr bool has_char_a(const char(&s)[N])
{
for (size_t i = 0; i < N; i++)
{
if (s[i] == 'a') return true;
}
return false;
}
template
constexpr const std::string make_string(const char(&s)[N])
{
static_assert(has_char_a(s), "error");
return std::string{ s, N };
}
void test()
{
cout << has_char_a("abc") << endl;
cout << make_string("abc") << endl;
}
La compilación falla en la línea con static_assert(has_char_a(s), "error");
,
Error C2131 la expresión no se evaluó como una constante
También intenté static_assert(has_char_a(s), "error");
, y también falló.
¿Cuál es el problema?
Editar: aunque esta publicación está cerrada, quiero dar mi propia explicación del problema.
Puedes depurar has_char_a, y se ejecutará en cada iteración del bucle for, así que no es una expresión const. La causa raíz es algo como esto:
constexpr int a = (int)(const char*)"abc";
Aunque "abc" es una constante, la dirección del puntero, la dirección de la cadena, no se decide durante el tiempo de compilación. Por lo tanto, no puede ser un constexpr.
davy.ai
El problema con el código es que la función
has_char_a
no es una funciónconstexpr
. La declaraciónstatic_assert
en la funciónmake_string
requiere quehas_char_a
sea una funciónconstexpr
ya que se utiliza como argumento de plantilla paraN
. Sin embargo, debido a quehas_char_a
contiene un bucle, no puede evaluarse en tiempo de compilación.Para solucionar este problema, puedes convertir
has_char_a
en una funciónconstexpr
utilizando una expresión de pliegue (disponible desde C++17) en lugar de un bucle. Aquí está la funciónhas_char_a
actualizada:c++
template <int n="">
constexpr bool has_char_a(const char(&s)[N])
{
return ((s[i] == 'a') || ...);
}
Con este cambio, la declaración
static_assert
enmake_string
debería funcionar correctamente.