¿Cuál es el punto de saber si un objeto es una integral o no o es un tipo de clase o no?

14

Hola, he visto muchos ejemplos como este en Cppreference.com:

std::is_class<T>
std::is_integral

Y así. Sé que si ejecuto el código, por ejemplo, obtengo trueo false. ¿Pero cuál es el punto en eso? por ejemplo, ¿saber que el objeto es de tipo de clase o no?

#include <iostream>
#include <type_traits>

struct A {};
class B {};
enum class C {};

int main()
{
    std::cout << std::boolalpha;
    std::cout << std::is_class<A>::value << '\n';
    std::cout << std::is_class<B>::value << '\n';
    std::cout << std::is_class<C>::value << '\n';
    std::cout << std::is_class<int>::value << '\n';
}

La salida:

true
true
false
false
  • He buscado por todas partes para un ejemplo real usando este ( is_class, is_integral, is_arithmetic, ...) Pero todos los tutoriales mostrar sólo la esperanza ejemplo: solamente trueo false.

  • ¿Alguien podría ayudarme con un pequeño ejemplo útil usando estas plantillas?

Rami Yen
fuente
1
Un ejemplo simple - std::copy. ¿Qué pasa si los tipos a std::copyson "simples", como una matriz de into char? Lo usarías memcpy, ¿verdad? Entonces, ¿cómo se dice "Si el tipo es simple, use memcpy, de lo contrario use un ciclo" lento "?
PaulMcKenzie

Respuestas:

17

No es para escribir en la consola, eso es seguro.

En términos más generales, se pregunta: ¿cuál es el punto de los rasgos de tipo?

La respuesta es la metaprogramación de plantilla . Por ejemplo, puedo crear una especialización de plantilla que hace una cosa para los tipos integrales y otra para los tipos no integrales.

Aaron Bullman tiene una introducción simple a los rasgos tipográficos , al igual que Jacek aquí .

En mi opinión, la mayoría del uso de estas cosas se encontrará oculto en implementaciones de características geniales y clases y utilidades (es decir, en bibliotecas) como parte de la maquinaria de fondo que hace que todo funcione.

Otras lecturas:

La respuesta de rightfold en la primera da un excelente ejemplo de cuándo los rasgos son útiles:

Por ejemplo, una implementación de std::copypuede usar std::memcpyinternamente en lugar de un bucle explícito cuando los iteradores son punteros a los POD. Esto se puede lograr con SFINAE.

Carreras de ligereza en órbita
fuente
Entonces, quiere decir, por ejemplo, que puedo usarlos para deshabilitar algunas instancias de plantillas para un tipo específico, por ejemplo, es lógico deshabilitar una función Power<T>o clase con plantilla cuando el tipo de argumento no es integral, digamos std :: string?
Rami Yen
1
@RamiYen, sí, eso se conoce como SFINAE .
Chris
7

Es para meta programación de plantillas. Cuando no tenga idea de qué tipo (s) el usuario final pasará a la plantilla. A veces es para informar errores, a veces es para especializarse en los tipos pasados. A veces es una combinación.

Los ejemplos vistos en cppreference.com (por ejemplo, https://en.cppreference.com/w/cpp/types/is_enum ) están muy simplificados y solo muestran cómo usar el rasgo de una manera no típica. Casi nunca usaría estos rasgos directamente en una simple (función o clase sin plantilla).

Richard Critten
fuente