es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema con el código es que la función has_char_a no es una función constexpr. La declaración static_assert en la función make_string requiere que has_char_a sea una función constexpr ya que se utiliza como argumento de plantilla para N. Sin embargo, debido a que has_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ón constexpr utilizando una expresión de pliegue (disponible desde C++17) en lugar de un bucle. Aquí está la función has_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 en make_string debería funcionar correctamente.

Comments are closed.