Namensräume
Varianten
Aktionen

std::conjunction

Von cppreference.com
< cpp‎ | types
 
 
Metaprogrammierungsbibliothek
Typmerkmale
Typkategorien
(C++11)
(C++11)(DR*)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11) 
(C++11)
(C++11)
Typeneigenschaften
(C++11)
(C++11)
(C++14)
(C++11)(deprecated in C++26)
(C++11)(bis C++20*)
(C++11)(veraltet in C++20)
(C++11)
Typmerkmalskonstanten
Metafunktionen
conjunction
(C++17)
(C++17)
Unterstützte Operationen
Beziehungen und Eigenschaftsabfragen
Typmodifikationen
(C++11)(C++11)(C++11)
Typentransformationen
(C++11)(veraltet in C++23)
(C++11)(veraltet in C++23)
(C++11)
(C++11)(bis C++20*)(C++17)

(C++11)
(C++11)
(C++17)
Rationale Arithmetik zur Compilezeit
Ganzzahlsequenzen zur Compilezeit
 
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 Bi in B1, ..., BN, für den bool(Bi::value) == false gilt, oder BN, 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) [bearbeiten]
variadische logische OR-Metafunktion
(Klassenvorlage) [bearbeiten]