std::common_reference
| Definiert in der Kopfdatei <type_traits> |
||
| template< class... T > struct common_reference; |
(seit C++20) | |
Bestimmt den gemeinsamen Referenztyp der Typen T..., d. h. den Typ, in den alle Typen in T... konvertiert oder an den sie gebunden werden können. Wenn ein solcher Typ existiert (gemäß den untenstehenden Regeln), benennt das Element type diesen Typ. Andernfalls gibt es kein Element type. Das Verhalten ist undefiniert, wenn einer der Typen in T... ein unvollständiger Typ ist, der von (möglicherweise cv-qualifiziertem) void abweicht.
Bei Referenztypen versucht common_reference, einen Referenztyp zu finden, an den alle angegebenen Referenztypen gebunden werden können, kann aber einen Nicht-Referenztyp zurückgeben, wenn kein solcher Referenztyp gefunden werden kann.
- Wenn sizeof...(T) null ist, gibt es kein Element
type. - Wenn sizeof...(T) eins ist (d. h.
T...enthält nur einen TypT0), benennt das Elementtypedenselben Typ wie T0. - Wenn sizeof...(T) zwei ist (d. h.
T...enthält zwei TypenT1undT2)- Sei
Sder *einfache gemeinsame Referenztyp* vonT1undT2(wie unten definiert). Das ElementtypebenenntS, wenn alle untenstehenden Bedingungen erfüllt sind.-
T1undT2sind beides Referenztypen. -
Sist wohlgeformt.
-
- Sei
|
(seit C++23) |
- Andernfalls, wenn std::basic_common_reference<std::remove_cvref_t<T1>, std::remove_cvref_t<T2>, T1Q, T2Q>::type existiert, wobei
TiQeine unäre Alias-Template ist, so dass TiQ<U>Umit dem Hinzufügen vonTi's cv- und Referenzqualifizierern ist, dann benennt das Elementtypediesen Typ;
- Andernfalls, wenn std::basic_common_reference<std::remove_cvref_t<T1>, std::remove_cvref_t<T2>, T1Q, T2Q>::type existiert, wobei
- Andernfalls, wenn decltype(false? val<T1>() : val<T2>()), wobei
valein Funktionstemplates template<class T> T val(); ist, ein gültiger Typ ist, dann benennt das Elementtypediesen Typ; - Andernfalls, wenn std::common_type_t<T1, T2> ein gültiger Typ ist, dann benennt das Element
typediesen Typ; - Andernfalls gibt es kein Element
type.
- Andernfalls, wenn decltype(false? val<T1>() : val<T2>()), wobei
- Wenn sizeof...(T) größer als zwei ist (d. h.
T...besteht aus den TypenT1, T2, R...), dann, wenn std::common_reference_t<T1, T2> existiert, bezeichnet das Elementtypestd::common_reference_t<std::common_reference_t<T1, T2>, R...>, falls ein solcher Typ existiert. In allen anderen Fällen gibt es kein Elementtype.
Der *einfache gemeinsame Referenztyp* von zwei Referenztypen T1 und T2 ist wie folgt definiert:
- Wenn
T1cv1 X&undT2cv2 Y&ist (d. h. beide sind lvalue-Referenztypen): ihr einfacher gemeinsamer Referenztyp ist decltype(false? std::declval<cv12 X&>() : std::declval<cv12 Y&>()), wobei cv12 die Vereinigung von cv1 und cv2 ist, wenn dieser Typ existiert und ein Referenztyp ist; - Wenn
T1undT2beides rvalue-Referenztypen sind: wenn der einfache gemeinsame Referenztyp vonT1&undT2&(gemäß dem vorherigen Punkt bestimmt) existiert, dann seiCder entsprechende rvalue-Referenztyp dieses Typs. Wenn std::is_convertible_v<T1, C> und std::is_convertible_v<T2, C> beide true sind, dann ist der einfache gemeinsame Referenztyp vonT1undT2C; - Andernfalls muss einer der beiden Typen ein lvalue-Referenztyp
A&und der andere ein rvalue-ReferenztypB&&sein (AundBkönnen cv-qualifiziert sein). SeiDder einfache gemeinsame Referenztyp von A& und B const&, falls vorhanden. Wenn D existiert und std::is_convertible_v<B&&, D> true ist, dann ist der einfache gemeinsame ReferenztypD; - Andernfalls gibt es keinen einfachen gemeinsamen Referenztyp.
Siehe Bedingungsoperator für die Definition des Typs des Ausdrucks false ? X : Y, wie sie oben verwendet werden.
Inhalt |
[edit] Member types
| Name | Definition |
type
|
der gemeinsame Referenztyp für alle T... |
[edit] Helper types
| template< class... T > using common_reference_t = std::common_reference<T...>::type; |
||
| template< class T, class U, template<class> class TQual, template<class> class UQual > struct basic_common_reference {}; |
||
Die Klassenvorlage basic_common_reference ist ein Anpassungspunkt, der es Benutzern ermöglicht, das Ergebnis von common_reference für benutzerdefinierte Typen (typischerweise Proxy-Referenzen) zu beeinflussen. Die primäre Vorlage ist leer.
[edit] Spezialisierungen
Ein Programm kann std::basic_common_reference<T, U, TQual, UQual> auf die ersten beiden Parameter T und U spezialisieren, wenn std::is_same_v<T, std::decay_t<T>> und std::is_same_v<U, std::decay_t<U>> beide true sind und mindestens einer von ihnen von einem programmintern definierten Typ abhängt.
Wenn eine solche Spezialisierung ein Element namens type hat, muss dieses ein öffentliches und eindeutiges Element sein, das einen Typ benennt, in den sowohl TQual<T> als auch UQual<U> konvertierbar sind. Zusätzlich müssen std::basic_common_reference<T, U, TQual, UQual>::type und std::basic_common_reference<U, T, UQual, TQual>::type denselben Typ bezeichnen.
Ein Programm darf basic_common_reference nicht auf den dritten oder vierten Parametern spezialisieren, noch darf es common_reference selbst spezialisieren. Ein Programm, das Spezialisierungen hinzufügt, die gegen diese Regeln verstoßen, hat undefiniertes Verhalten.
Die Standardbibliothek stellt folgende Spezialisierungen von basic_common_reference bereit:
ermittelt den gemeinsamen Referenztyp von zwei pairs(Klassenvorlagenspezialisierung) | |
ermittelt den gemeinsamen Referenztyp eines tuple und eines tuple-like Typs(class template specialization) | |
bestimmt den gemeinsamen Referenztyp von reference_wrapper und Nicht-reference_wrapper(class template specialization) |
[edit] Notes
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_common_reference |
202302L |
(C++23) | std::common_reference_t von std::reference_wrapper zu einem Referenztyp machen |
[edit] Examples
#include <concepts> #include <type_traits> static_assert( std::same_as< int&, std::common_reference_t< std::add_lvalue_reference_t<int>, std::add_lvalue_reference_t<int>&, std::add_lvalue_reference_t<int>&&, std::add_lvalue_reference_t<int>const, std::add_lvalue_reference_t<int>const& > > ); int main() {}
[edit] See also
| (C++11) |
ermittelt den gemeinsamen Typ einer Gruppe von Typen (Klassenvorlage) |
| (C++20) |
gibt an, dass zwei Typen einen gemeinsamen Referenztyp haben (Konzept) |