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.

Fallback por defecto para funciones de plantilla en C++ usando enable_if

Quiero escribir un mecanismo de C++, donde diferentes instanciaciones de una función son llamadas si una clase dada Param es derivada de una cierta clase base.

Esto funciona bastante bien con std::is_base_of y std::enable_if.

Sin embargo, me gustaría tener una “versión por defecto” de esta función doStuff() que sea llamada para “todas las demás clases”.
Esto básicamente funcionaría haciendo algo como “si Param no es derivado de A y si no es derivado de B”, pero me pregunto si hay una solución más elegante.


#include <iostream> class A {}; class B : public A {}; class X {}; class Y : public X {}; class Other {}; template <typename param,=""></typename><><a, param="">::value, bool> = true> void doStuff() {std::cout << "Base A" << std::endl;} template <typename param,=""></typename><><x, param="">::value, bool> = true> void doStuff() {std::cout << "Base X" << std::endl;} int main() { doStuff<b>(); doStuff<y>(); // doStuff<other>(); esto no es derivado ni de B ni de Y, por lo que se llama al caso por defecto }

La solución debe funcionar con C++14.</x,></a,>

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Una posible solución es utilizar una combinación de std::is_base_of y std::disjunction para crear un rasgo de tipo que verifique si Param no está derivado de ninguna de las clases especificadas. Luego, utiliza std::enable_if con la negación de este rasgo de tipo para habilitar la versión predeterminada de doStuff() para todas las demás clases:

    “`c++
    #include
    #include

    class A {};

    class B : public A {};

    class X {};

    class Y : public X {};

    class Other {};

    template <><a, param=””>::value, bool> = true>
    void doStuff() { std::cout << “Base A” << std::endl; }

    template <><x, param=””>::value, bool> = true>
    void doStuff() { std::cout << “Base X” << std::endl; }

    template <!std::disjunction_v<std::is_base_of<A, Param>,
    std::is_base_of<x, param=””>>, bool> = true>
    void doStuff() { std::cout << “Caso predeterminado” << std::endl; }

    int main() {
    doStuff();
    doStuff();
    doStuff(); // llama al caso predeterminado
    }
    “`

    Aquí, el rasgo de tipo std::disjunction se utiliza para combinar varias comprobaciones de std::is_base_of, y su variable miembro estática std::disjunction_v devuelve true si al menos una de las comprobaciones devuelve true. Utilizando std::enable_if con la negación de este rasgo de tipo significa que la versión predeterminada de doStuff() solo se habilita si Param no está derivado de ninguna de las clases especificadas.</x,></x,></a,>

Comments are closed.