std::conjunction
| Definiert in der Kopfdatei <type_traits> |
||
| template< class... B > struct conjunction; |
(seit C++17) | |
Bildet die logische Konjunktion der Typ-Traits B... und führt effektiv ein logisches AND für die Sequenz von Traits aus.
Die Spezialisierung std::conjunction<B1, ..., BN> hat eine öffentliche und eindeutige Basis, die ist
- wenn sizeof...(B) == 0, std::true_type; andernfalls
- der erste Typ
BiinB1, ..., BN, für den bool(Bi::value) == false gilt, oderBN, wenn kein solcher Typ existiert.
Die Mitgliedsnamen der Basisklasse, außer conjunction und operator=, werden nicht versteckt und sind in conjunction eindeutig verfügbar.
Die Konjunktion ist kurzschließend: Wenn es ein Template-Typ-Argument Bi gibt, für das bool(Bi::value) == false gilt, dann erfordert die Instanziierung von conjunction<B1, ..., BN>::value nicht die Instanziierung von Bj::value für j > i.
Wenn das Programm Spezialisierungen für std::conjunction oder std::conjunction_v hinzufügt, ist das Verhalten undefiniert.
Inhalt |
[edit] Template-Parameter
| B... | - | Jedes Template-Argument Bi, für das Bi::value instanziiert wird, muss als Basisklasse verwendbar sein und ein Mitglied value definieren, das in bool konvertierbar ist. |
[edit] Hilfsvariablen-Template
| template< class... B > constexpr bool conjunction_v = conjunction<B...>::value; |
(seit C++17) | |
[edit] Mögliche Implementierung
template<class...> struct conjunction : std::true_type {}; template<class B1> struct conjunction<B1> : B1 {}; template<class B1, class... Bn> struct conjunction<B1, Bn...> : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {}; |
[edit] Hinweise
Eine Spezialisierung von conjunction erbt nicht notwendigerweise von std::true_type oder std::false_type: Sie erbt einfach vom ersten B, dessen ::value, explizit in bool konvertiert, false ist, oder vom allerletzten B, wenn alle zu true konvertieren. Zum Beispiel ist std::conjunction<std::integral_constant<int, 2>, std::integral_constant<int, 4>>::value 4.
Die kurzschließende Instanziierung unterscheidet conjunction von Fold-Ausdrücken: Ein Fold-Ausdruck wie (... && Bs::value) instanziiert jedes B in Bs, während std::conjunction_v<Bs...> die Instanziierung stoppt, sobald der Wert bestimmt werden kann. Dies ist besonders nützlich, wenn die spätere Instanziierung teuer ist oder einen harten Fehler verursachen kann, wenn sie mit dem falschen Typ instanziiert wird.
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_logical_traits |
201510L |
(C++17) | Typ-Traits für logische Operatoren |
[edit] Beispiel
#include <iostream> #include <type_traits> // func is enabled if all Ts... have the same type as T template<typename T, typename... Ts> std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...>> func(T, Ts...) { std::cout << "All types in pack are the same.\n"; } // otherwise template<typename T, typename... Ts> std::enable_if_t<!std::conjunction_v<std::is_same<T, Ts>...>> func(T, Ts...) { std::cout << "Not all types in pack are the same.\n"; } template<typename T, typename... Ts> constexpr bool all_types_are_same = std::conjunction_v<std::is_same<T, Ts>...>; static_assert(all_types_are_same<int, int, int>); static_assert(not all_types_are_same<int, int&, int>); int main() { func(1, 2, 3); func(1, 2, "hello!"); }
Ausgabe
All types in pack are the same. Not all types in pack are the same.
[edit] Siehe auch
| (C++17) |
logische NOT-Metafunktion (Klassenvorlage) |
| (C++17) |
variadische logische OR-Metafunktion (Klassenvorlage) |