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.

¿Puedo determinar en tiempo de compilación si una especialización de plantilla eventualmente fallará?

¿Es posible saber en tiempo de compilación si una especialización de plantilla con los parámetros dados produciría un error en tiempo de compilación?

Lo siguiente fallará en tiempo de compilación. ¿Es posible determinar esto sin saber nada sobre std::find y sin obtener el error en tiempo de compilación?

int a;
std::vector< std::vector<int> > v;     
std::vector< std::vector<int> >::iterator it = std::find(v.begin(), v.end(), a);

Supongo que mi programa, con o sin la especialización de plantilla, compilará o fallará en un tiempo finito. Con suerte, esto evita la preocupación del problema de detención.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible determinar en tiempo de compilación que una especialización de plantilla con ciertos parámetros produciría un error de tiempo de compilación. Esto se puede lograr utilizando una técnica llamada “SFINAE” (Substitution Failure Is Not An Error), que es una técnica de metaprogramación de plantillas utilizada para probar la existencia de una sustitución válida para un paquete de parámetros de plantilla. En este caso, podemos usar SFINAE para probar si se puede llamar a std::find con los argumentos especificados.

    Podemos definir una clase de plantilla auxiliar que determine si una expresión dada es válida o no utilizando SFINAE. Aquí hay una implementación de ejemplo:

    template<typename t="">
    struct is_findable {
    private:
        template<typename u="">
        static auto test(U &&u) -> decltype(
            std::declval<typename></typename><u>::type::iterator>(),
            std::declval<typename></typename><u>::type::value_type>(),
            std::declval<const typename=""></const><u>::type &>().begin(),
            std::declval<const typename=""></const><u>::type &>().end(),
            std::true_type()
        );
        template<typename u="">
        static std::false_type test(...);
    
    public:
        static constexpr bool value = decltype(test<t>(std::declval<t>()))::value;
    };
    

    Esta clase de plantilla utiliza dos funciones auxiliares privadas, “test” y “test”, para comprobar si una expresión dada es válida. La función “test” intenta llamar a “std::find” con los argumentos dados y devuelve “std::true_type” si la llamada es válida. La función “test” utiliza la sintaxis de “puntos suspensivos” (“…”) para hacer coincidir cualquier argumento, indicando que la función se puede llamar con cualquier paquete de parámetros.

    Luego podemos verificar si una llamada a “std::find” con los argumentos dados es válida utilizando “is_findable”:

    static_assert(is_findable<decltype(std::find(v.begin(), v.end(),="" a))="">::value,
                  "std::find no es llamable con estos argumentos");
    

    Esto producirá un error de tiempo de compilación si la llamada a “std::find” no es válida, informándonos que una especialización de la plantilla con estos argumentos también produciría un error de tiempo de compilación.</decltype(std::find(v.begin(),>

Comments are closed.