Was bringt es, zu wissen, ob ein Objekt ein Integral ist oder nicht oder ein Klassentyp ist oder nicht?

14

Hallo, ich habe viele Beispiele wie dieses in Cppreference.com gesehen:

std::is_class<T>
std::is_integral

Und so weiter. Ich weiß, ob ich den Code zum Beispiel bekomme trueoder bekomme false. Aber worum geht es dabei? zB zu wissen, dass das Objekt vom Klassentyp ist oder nicht?

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

Die Ausgabe:

true
true
false
false
  • Ich habe gesucht alle über ein reales Beispiel mit diesem ( is_class, is_integral, is_arithmetic, ...) Aber alle die Tutorials zeigen nur die hoffnungslos Beispiel: nur truenoch false.

  • Könnte mir jemand mit einem kleinen nützlichen Beispiel helfen, das diese Vorlagen verwendet?

Rami Yen
quelle
1
Ein einfaches Beispiel - std::copy. Was ist, wenn die Typen std::copy"einfach" sind, wie ein Array von intoder char? Sie würden verwenden memcpy, richtig? Wie sagt man also "Wenn der Typ einfach ist, benutze memcpy, sonst benutze eine" langsame "Schleife"?
PaulMcKenzie

Antworten:

17

Es ist nicht zum Schreiben auf die Konsole gedacht, das ist sicher.

Im weiteren Sinne fragen Sie: Was ist der Sinn von Typmerkmalen?

Die Antwort ist Vorlagen-Metaprogrammierung . Zum Beispiel kann ich eine Vorlagenspezialisierung erstellen, die eine Sache für integrale Typen und eine andere für nicht integrale Typen erledigt.

Aaron Bullman hat eine einfache Einführung in Typmerkmale, genau wie Jacek hier .

Meiner Meinung nach wird die meiste Verwendung dieser Dinge in Implementierungen cooler Funktionen und Klassen und Dienstprogramme (dh in Bibliotheken) als Teil der Hintergrundmaschinerie vergraben sein, mit der alles funktioniert.

Weiterführende Literatur:

Die Antwort von rightfold auf diese erste gibt ein hervorragendes Beispiel dafür, wann Eigenschaften nützlich sind:

Zum Beispiel kann eine Implementierung von std::copyMai Verwendung std::memcpyintern statt eine explizite Schleife , wenn die Iteratoren sind Zeiger auf PODs. Dies kann mit SFINAE erreicht werden.

Leichtigkeitsrennen im Orbit
quelle
Sie meinen also, ich kann sie verwenden, um einige Instanzen von Vorlagen für einen bestimmten Typ zu deaktivieren. Zum Beispiel ist es logisch, eine Vorlagenfunktion Power<T>oder -klasse zu deaktivieren, wenn der Argumenttyp nicht ganzzahlig ist. Sagen wir std :: string?
Rami Yen
1
@RamiYen, ja, das wird als SFINAE bezeichnet .
Chris
7

Es ist für die Template-Meta-Programmierung. Wenn Sie keine Ahnung haben, welche Typen der Endbenutzer an die Vorlage weitergibt. Manchmal geht es darum, Fehler zu melden, manchmal um sich auf die übergebenen Typen zu spezialisieren. Manchmal ist es eine Kombination.

Die Beispiele auf cppreference.com (z. B. https://en.cppreference.com/w/cpp/types/is_enum ) sind stark vereinfacht und zeigen nur, wie das Merkmal auf nicht typische Weise verwendet wird. Sie würden diese Merkmale fast nie direkt in einer einfachen Funktion (ohne Vorlage oder in einer Klasse) verwenden.

Richard Critten
quelle