Quel est l'intérêt de savoir si un objet est intégral ou non ou est un type de classe ou non?

14

Bonjour, j'ai vu de nombreux exemples comme celui-ci dans Cppreference.com:

std::is_class<T>
std::is_integral

Etc. Je sais que si j'exécute le code, par exemple, j'obtiens trueou false. Mais à quoi ça sert? Par exemple, savoir que l'objet est de type classe ou non?

#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';
}

Le résultat:

true
true
false
false
  • Je l' ai cherché partout pour un exemple réel en utilisant cette ( is_class, is_integral, is_arithmetic, ...) Mais tous les tutoriels ne montre que l'exemple sans espoir: que trueou false.

  • Quelqu'un pourrait-il m'aider avec un petit exemple utile en utilisant ces modèles?

Rami Yen
la source
1
Un exemple simple - std::copy. Et si les types à std::copysont "simples", comme un tableau de intou char? Vous utiliseriez memcpy, non? Alors, comment dites-vous "Si le type est simple, utilisez memcpy, sinon utilisez une boucle" lente ""?
PaulMcKenzie

Réponses:

17

Ce n'est pas pour écrire sur la console, c'est sûr.

Plus largement, vous vous demandez: à quoi servent les traits de caractères?

La réponse est une métaprogrammation de modèle . Par exemple, je peux créer une spécialisation de modèle qui fait une chose pour les types intégraux et une autre pour les types non intégraux.

Aaron Bullman a une introduction simple aux caractères de type , tout comme Jacek ici .

À mon avis, la plupart de l' utilisation de ces choses se trouvera enfouie dans les implémentations de fonctionnalités et de classes et d'utilitaires sympas (c'est-à-dire dans les bibliothèques) dans le cadre de la machinerie d'arrière-plan qui fait tout fonctionner.

Lectures complémentaires:

la réponse de rightfold sur cette première donne un superbe exemple de quand les traits sont utiles:

Par exemple, une implémentation de std::copypeut utiliser en std::memcpyinterne au lieu d'une boucle explicite lorsque les itérateurs sont des pointeurs vers des POD. Cela peut être réalisé avec SFINAE.

Courses de légèreté en orbite
la source
Donc, vous voulez dire par exemple que je peux les utiliser pour désactiver certaines instances de modèles pour un type spécifique, par exemple, il est logique de désactiver une fonction Power<T>ou une classe de modèle lorsque le type d'argument n'est pas intégral, disons std :: string?
Rami Yen
1
@RamiYen, oui, c'est ce qu'on appelle SFINAE .
chris
7

C'est pour la méta-programmation de modèles. Lorsque vous ne savez pas quel (s) type (s) l'utilisateur final passera dans le modèle. Parfois c'est pour signaler des erreurs, parfois c'est pour se spécialiser sur les types passés. Parfois, c'est une combinaison.

Les exemples vus sur cppreference.com (par exemple https://en.cppreference.com/w/cpp/types/is_enum ) sont beaucoup trop simplifiés et montrent simplement comment utiliser le trait d'une manière non typique. Vous n'utiliseriez presque jamais ces traits directement dans une simple (fonction ou classe non-modèle).

Richard Critten
la source