std::is_base_of
| Definiert in der Kopfdatei <type_traits> |
||
| template< class Base, class Derived > struct is_base_of; |
(seit C++11) | |
std::is_base_of ist ein BinaryTypeTrait.
Wenn Derived von Base abgeleitet ist oder wenn beide dieselbe Nicht-Union-Klasse sind (in beiden Fällen unter Ignorierung der cv-Qualifizierung), stellt es die Member-Konstante value mit dem Wert true bereit. Andernfalls ist value false.
Wenn sowohl Base als auch Derived Nicht-Union-Klassentypen sind und sie nicht derselbe Typ sind (unter Ignorierung der cv-Qualifizierung), sollte Derived ein vollständiger Typ sein; andernfalls ist das Verhalten undefiniert.
Wenn das Programm Spezialisierungen für std::is_base_of oder std::is_base_of_v(seit C++17) hinzufügt, ist das Verhalten undefiniert.
Inhalt |
[bearbeiten] Hilfsvariablentemplate
| template< class Base, class Derived > constexpr bool is_base_of_v = is_base_of<Base, Derived>::value; |
(seit C++17) | |
Abgeleitet von std::integral_constant
Member-Konstanten
| value [static] |
true wenn Derived von Base abgeleitet ist oder wenn beide dieselbe Nicht-Union-Klasse sind (in beiden Fällen unter Ignorierung der cv-Qualifizierung), false andernfalls(öffentliche statische Member-Konstante) |
Memberfunktionen
| operator bool |
konvertiert das Objekt zu bool, gibt value zurück (öffentliche Memberfunktion) |
| operator() (C++14) |
gibt value zurück (öffentliche Memberfunktion) |
Membertypen
| Typ | Definition |
value_type
|
bool |
type
|
std::integral_constant<bool, value> |
[bearbeiten] Anmerkungen
std::is_base_of<A, B>::value ist true, auch wenn A eine private, protected oder mehrdeutige Basisklasse von B ist. In vielen Situationen ist std::is_convertible<B*, A*> die passendere Prüfung.
Obwohl keine Klasse ihre eigene Basis ist, ist std::is_base_of<T, T>::value true, da die Absicht des Traits darin besteht, die "is-a"-Beziehung zu modellieren, und T ein T ist. Trotzdem ist std::is_base_of<int, int>::value false, da nur Klassen an der Beziehung teilnehmen, die dieser Trait modelliert.
[bearbeiten] Mögliche Implementierung
namespace details { template<typename B> std::true_type test_ptr_conv(const volatile B*); template<typename> std::false_type test_ptr_conv(const volatile void*); template<typename B, typename D> auto test_is_base_of(int) -> decltype(test_ptr_conv<B>(static_cast<D*>(nullptr))); template<typename, typename> auto test_is_base_of(...) -> std::true_type; // private or ambiguous base } template<typename Base, typename Derived> struct is_base_of : std::integral_constant< bool, std::is_class<Base>::value && std::is_class<Derived>::value && decltype(details::test_is_base_of<Base, Derived>(0))::value > {}; |
[bearbeiten] Beispiel
#include <type_traits> class A {}; class B : A {}; class C : B {}; class D {}; union E {}; using I = int; static_assert ( std::is_base_of_v<A, A> == true && std::is_base_of_v<A, B> == true && std::is_base_of_v<A, C> == true && std::is_base_of_v<A, D> != true && std::is_base_of_v<B, A> != true && std::is_base_of_v<E, E> != true && std::is_base_of_v<I, I> != true ); int main() {}
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 2015 | C++11 | das Verhalten kann undefiniert sein, wennDerived ein unvollständiger Union-Typ ist |
Die Basischarakteristik ist std::false_type in diesem Fall |
[bearbeiten] Siehe auch
| (C++26) |
prüft, ob ein Typ eine virtuelle Basisklasse des anderen Typs ist (Klassenvorlage) |
| (C++11)(C++20) |
prüft, ob ein Typ in den anderen Typ konvertierbar ist (Klassenvorlage) |
| (C++20) |
gibt an, dass ein Typ von einem anderen Typ abgeleitet ist (Konzept) |