std:: disjunction
|
Definiert im Header
<type_traits>
|
||
|
template
<
class
...
B
>
struct disjunction ; |
(seit C++17) | |
Bildet die logische Disjunktion der Type-Traits B... , was effektiv eine logische OR-Operation auf der Sequenz von Traits durchführt.
Die Spezialisierung std :: disjunction < B1, ..., BN > hat eine öffentliche und eindeutige Basis, die
- falls sizeof... ( B ) == 0 , std:: false_type ; andernfalls
-
der erste Typ
BiinB1, ..., BNfür den bool ( Bi :: value ) == true , oderBNfalls kein solcher Typ existiert.
Die Member-Namen der Basisklasse, außer
disjunction
und
operator=
, werden nicht verborgen und sind in
disjunction
eindeutig verfügbar.
Disjunktion ist kurzschließend: wenn es ein Template-Typenargument
Bi
gibt mit
bool
(
Bi
::
value
)
!
=
false
, dann erfordert die Instanziierung von
disjunction
<
B1, ..., BN
>
::
value
nicht die Instanziierung von
Bj
::
value
für
j > i
.
Wenn das Programm Spezialisierungen für
std::disjunction
oder
std::disjunction_v
hinzufügt, ist das Verhalten undefiniert.
Inhaltsverzeichnis |
Template-Parameter
| B... | - |
jedes Template-Argument
Bi
für das
Bi
::
value
instanziiert wird, muss als Basisklasse verwendbar sein und ein Member
value
definieren, das in
bool
konvertierbar ist
|
Hilfsvariablen-Template
|
template
<
class
...
B
>
constexpr bool disjunction_v = disjunction < B... > :: value ; |
(seit C++17) | |
Mögliche Implementierung
template<class...> struct disjunction : std::false_type {}; template<class B1> struct disjunction<B1> : B1 {}; template<class B1, class... Bn> struct disjunction<B1, Bn...> : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>> {}; |
Hinweise
Eine Spezialisierung von
disjunction
erbt nicht notwendigerweise von
std::
true_type
oder
std::
false_type
: sie erbt einfach vom ersten
B
, dessen
::value
, explizit konvertiert zu
bool
,
true
ist, oder vom letzten
B
, wenn alle zu
false
konvertieren. Zum Beispiel ist
std
::
disjunction
<
std::
integral_constant
<
int
,
2
>
,
std::
integral_constant
<
int
,
4
>>
::
value
gleich
2
.
Die Kurzschluss-Instanziierung unterscheidet
disjunction
von
Fold-Ausdrücken
: Ein Fold-Ausdruck wie
(
...
||
Bs
::
value
)
instanziiert jedes
B
in
Bs
, während
std
::
disjunction_v
<
Bs...
>
die Instanziierung stoppt, sobald der Wert bestimmt werden kann. Dies ist besonders nützlich, wenn der spätere Typ aufwändig zu instanziieren ist oder einen schwerwiegenden Fehler verursachen kann, wenn er mit dem falschen Typ instanziiert wird.
| Feature-Test Makro | Wert | Standard | Feature |
|---|---|---|---|
__cpp_lib_logical_traits
|
201510L
|
(C++17) | Logische Operator-Typ-Traits |
Beispiel
#include <cstdint> #include <string> #include <type_traits> // values_equal<a, b, T>::value ist true genau dann wenn a == b. template<auto V1, decltype(V1) V2, typename T> struct values_equal : std::bool_constant<V1 == V2> { using type = T; }; // default_type<T>::value ist immer true template<typename T> struct default_type : std::true_type { using type = T; }; // Jetzt können wir Disjunktion wie eine switch-Anweisung verwenden: template<int I> using int_of_size = typename std::disjunction< // values_equal<I, 1, std::int8_t>, // values_equal<I, 2, std::int16_t>, // values_equal<I, 4, std::int32_t>, // values_equal<I, 8, std::int64_t>, // default_type<void> // muss zuletzt stehen! >::type; static_assert(sizeof(int_of_size<1>) == 1); static_assert(sizeof(int_of_size<2>) == 2); static_assert(sizeof(int_of_size<4>) == 4); static_assert(sizeof(int_of_size<8>) == 8); static_assert(std::is_same_v<int_of_size<13>, void>); // Die Überprüfung, ob Foo aus double konstruierbar ist, wird einen schwerwiegenden Fehler verursachen struct Foo { template<class T> struct sfinae_unfriendly_check { static_assert(!std::is_same_v<T, double>); }; template<class T> Foo(T, sfinae_unfriendly_check<T> = {}); }; template<class... Ts> struct first_constructible { template<class T, class...Args> struct is_constructible_x : std::is_constructible<T, Args...> { using type = T; }; struct fallback { static constexpr bool value = true; using type = void; // Typ, der zurückgegeben wird, wenn nichts gefunden wurde }; template<class... Args> using with = typename std::disjunction<is_constructible_x<Ts, Args...>..., fallback>::type; }; // OK, is_constructible<Foo, double> nicht instanziiert static_assert(std::is_same_v<first_constructible<std::string, int, Foo>::mit<double>, int>); static_assert(std::is_same_v<first_constructible<std::string, int>::mit<>, std::string>); static_assert(std::is_same_v<first_constructible<std::string, int>::mit<const char*>, std::string>); static_assert(std::is_same_v<first_constructible<std::string, int>::mit<void*>, void>); int main() {}
Siehe auch
|
(C++17)
|
logische NOT-Metafunktion
(Klassentemplate) |
|
(C++17)
|
variadische logische UND-Metafunktion
(Klassentemplate) |