Supongamos que tengo una plantilla de función y dos clases de

class animal {
}
class person {
}

template<class T>
void foo() {
  if (T is animal) {
    kill();
  }
}

¿Cómo puedo hacer el check para T es el animal? Yo no quiero tener
algo que se verifica durante el tiempo de ejecución. Gracias

  • Yo pondría «mascotas» en lugar de «matar» 🙂

4 Comentarios

  1. 87

    Uso is_same:

    #include <type_traits>
    
    template <typename T>
    void foo()
    {
        if (std::is_same<T, animal>::value) { /* ... */ }  //optimizable...
    }

    Generalmente, eso es totalmente inviable el diseño, sin embargo, y usted realmente quiere se especializan:

    template <typename T> void foo() { /* generic implementation  */ }
    
    template <> void foo<animal>()   { /* specific for T = animal */ }

    Tenga en cuenta también que no es habitual tener la función de las plantillas explícito (no deducida) argumentos. No es algo inaudito, pero a menudo hay mejores enfoques.

    • TThanks! En realidad comparten UNA gran cantidad de código así que realmente no puedo duplicarlo
    • Siempre puedes factor de código, de forma que el tipo de la parte dependiente puede ser relegada a un specializable función…
    • Un rápido seguimiento, si se me permite usar std::is_same, entonces NO va a ralentizar el código para otros parámetros de la plantilla, a la derecha?
    • El rasgo valores son estáticamente todos conocido. No hay ningún costo de tiempo de ejecución, siempre que su compilador es medio decente. Compruebe la asamblea en caso de duda, sin embargo.
    • Una pregunta: si yo sólo quiero se especializan el comportamiento del método de una y sólo una tipo específico, con C++11 plantilla por defecto de los parámetros de trabajo así?
    • Desde T no se deduce, no hay mucho que se puede hacer. Usted podría salir de la primaria plantilla no implementadas y crear una especialización, o puede agregar un estático afirmación con is_same.
    • Cómo saber el tipo de argumento que se pasa de tipos de datos simples, tales como si la int es pasado o el flotador se pasa?
    • ¿qué quiere decir? La función foo no tiene parámetros, por lo que no se pueden pasar argumentos a ella. Debe especificar el argumento de plantilla directamente. Y, a continuación, el código de la respuesta de la prueba para int y float, demasiado (is_same<T, int> etc.).

  2. 18

    Creo que hoy, es mejor utilizar, pero sólo con C++17.

    #include <type_traits>
    
    template <typename T>
    void foo() {
        if constexpr (std::is_same_v<T, animal>) {
            //use type specific operations... 
        } 
    }

    Si usted usa algún tipo de operaciones concretas, en el caso de la expresión corporal sin constexpr, este código no compila.

    • en lugar de std::is_same<T, U>::value usted podría utilizar más corto: std::is_same_v<T, U>
    • sí is_same_v, gracias
  3. 6

    En C++17, podemos utilizar variantes.

    Utilizar std::variant, deberá incluir el encabezado:

    #include <variant>

    Después de eso, usted puede agregar std::variant en su código como este:

    using Type = std::variant<Animal, Person>;
    
    template <class T>
    void foo(Type type) {
        if (std::is_same_v<type, Animal>) {
            //Do stuff...
        } else {
            //Do stuff...
        }
    }
    • ¿Cómo se T y Tipo conectado?
    • Ay, lo he corregido
    • Esta respuesta es problemático en varias maneras. Además de los errores (type que es el valor de tipo de Type o una plantilla que no tiene sentido aquí) is_same_v no es significativo en el contexto de variant. El correspondiente «rasgo» es holds_alternative.
  4. 5

    Se puede especializar sus plantillas en función de lo que pasa en sus parámetros como este:

    template <> void foo<animal> {
    
    }

    Tenga en cuenta que esto crea una totalmente nueva función que se basa en el tipo que se pasa como T. Este es generalmente preferible, ya que reduce el desorden y es básicamente la razón por la que tenemos plantillas en el primer lugar.

    • Hmm. Este método es realmente la única forma preferible para especializarse argumento de plantilla? Digamos que he 10 diferentes clases hijas que tengo que manejar dentro de la plantilla de función. ¿Realmente tengo que escribir 10 plantilla diferente de las funciones para la respectiva clase? Creo que puede ser falta el punto esencial aquí.
    • Esto realmente suena como una buena idea, aunque, si alguien no quiere usar type_traits. Como alguien mencionó la lógica principal se puede hacer en una función diferente, que acepta un indicador adicional para indicar el tipo, y esta especializada declaración sólo puede establecer el indicador en consecuencia y directamente pasar a todos los demás argumentos sin tocar nada. Así que si 10 clases diferentes necesitan ser manipulados, se trata básicamente de 10 líneas para 10 diferentes definiciones de función. Pero esto va a obtener una gran cantidad complicado si hay más de 1 variable de la plantilla.

Dejar respuesta

Please enter your comment!
Please enter your name here