Namensräume
Varianten
Aktionen

std::common_reference

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
(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)
common_reference
(C++20)
(C++11)
(C++17)
Rationale Arithmetik zur Compilezeit
Ganzzahlsequenzen zur Compilezeit
 
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 Typ T0), benennt das Element type denselben Typ wie T0.
  • Wenn sizeof...(T) zwei ist (d. h. T... enthält zwei Typen T1 und T2)
    • Sei S der *einfache gemeinsame Referenztyp* von T1 und T2 (wie unten definiert). Das Element type benennt S, wenn alle untenstehenden Bedingungen erfüllt sind.
      • T1 und T2 sind beides Referenztypen.
      • S ist wohlgeformt.
(seit C++23)
  • Andernfalls, wenn std::basic_common_reference<std::remove_cvref_t<T1>, std::remove_cvref_t<T2>, T1Q, T2Q>::type existiert, wobei TiQ eine unäre Alias-Template ist, so dass TiQ<U> U mit dem Hinzufügen von Ti's cv- und Referenzqualifizierern ist, dann benennt das Element type diesen Typ;
    • Andernfalls, wenn decltype(false? val<T1>() : val<T2>()), wobei val ein Funktionstemplates template<class T> T val(); ist, ein gültiger Typ ist, dann benennt das Element type diesen Typ;
    • Andernfalls, wenn std::common_type_t<T1, T2> ein gültiger Typ ist, dann benennt das Element type diesen Typ;
    • Andernfalls gibt es kein Element type.
  • Wenn sizeof...(T) größer als zwei ist (d. h. T... besteht aus den Typen T1, T2, R...), dann, wenn std::common_reference_t<T1, T2> existiert, bezeichnet das Element type std::common_reference_t<std::common_reference_t<T1, T2>, R...>, falls ein solcher Typ existiert. In allen anderen Fällen gibt es kein Element type.

Der *einfache gemeinsame Referenztyp* von zwei Referenztypen T1 und T2 ist wie folgt definiert:

  • Wenn T1 cv1 X& und T2 cv2 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 T1 und T2 beides rvalue-Referenztypen sind: wenn der einfache gemeinsame Referenztyp von T1& und T2& (gemäß dem vorherigen Punkt bestimmt) existiert, dann sei C der 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 von T1 und T2 C;
  • Andernfalls muss einer der beiden Typen ein lvalue-Referenztyp A& und der andere ein rvalue-Referenztyp B&& sein (A und B können cv-qualifiziert sein). Sei D der 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 Referenztyp D;
  • 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) [edit]
ermittelt den gemeinsamen Referenztyp eines tuple und eines tuple-like Typs
(class template specialization) [bearbeiten]
bestimmt den gemeinsamen Referenztyp von reference_wrapper und Nicht-reference_wrapper
(class template specialization) [edit]

[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

ermittelt den gemeinsamen Typ einer Gruppe von Typen
(Klassenvorlage) [bearbeiten]
gibt an, dass zwei Typen einen gemeinsamen Referenztyp haben
(Konzept) [bearbeiten]