std::add_lvalue_reference, std::add_rvalue_reference
Von cppreference.com
| Definiert in der Kopfdatei <type_traits> |
||
| template< class T > struct add_lvalue_reference; |
(1) | (seit C++11) |
| template< class T > struct add_rvalue_reference; |
(2) | (seit C++11) |
Erzeugt einen Lvalue- oder Rvalue-Referenztyp von T.
| Typ-Trait | Der Referenztyp im verschachtelten Typ type | |
|---|---|---|
T ist ein referenzierbarer Typ |
T ist kein referenzierbarer Typ | |
| (1) | T&[1] |
T
|
| (2) | T&&[2] | |
- ↑ Diese Regel spiegelt die Semantik von Referenzkollaps wider.
- ↑ Diese Regel spiegelt die Semantik von Referenzkollaps wider. Beachten Sie, dass std::add_rvalue_reference<T&>::type gleich
T&ist, was kein Rvalue-Referenztyp ist.
Wenn das Programm Spezialisierungen für eine der auf dieser Seite beschriebenen Vorlagen hinzufügt, ist das Verhalten undefiniert.
Inhalt |
[bearbeiten] Verschachtelte Typen
| Name | Definition |
type
|
wie oben bestimmt |
[bearbeiten] Hilfstypen
| template< class T > using add_lvalue_reference_t = typename add_lvalue_reference<T>::type; |
(seit C++14) | |
| template< class T > using add_rvalue_reference_t = typename add_rvalue_reference<T>::type; |
(seit C++14) | |
[bearbeiten] Notizen
Der Hauptunterschied zur direkten Verwendung von T& oder T&& besteht darin, dass T ein nicht referenzierbarer Typ sein kann. Zum Beispiel ist std::add_lvalue_reference<void>::type gleich void, während void& zu einem Kompilierungsfehler führt.
[bearbeiten] Mögliche Implementierung
namespace detail { template<class T> struct type_identity { using type = T; }; // or use std::type_identity (since C++20) template<class T> // Note that “cv void&” is a substitution failure auto try_add_lvalue_reference(int) -> type_identity<T&>; template<class T> // Handle T = cv void case auto try_add_lvalue_reference(...) -> type_identity<T>; template<class T> auto try_add_rvalue_reference(int) -> type_identity<T&&>; template<class T> auto try_add_rvalue_reference(...) -> type_identity<T>; } // namespace detail template<class T> struct add_lvalue_reference : decltype(detail::try_add_lvalue_reference<T>(0)) {}; template<class T> struct add_rvalue_reference : decltype(detail::try_add_rvalue_reference<T>(0)) {}; |
[bearbeiten] Beispiel
Führen Sie diesen Code aus
#include <type_traits> using non_ref = int; static_assert(std::is_lvalue_reference_v<non_ref> == false); using l_ref = std::add_lvalue_reference_t<non_ref>; static_assert(std::is_lvalue_reference_v<l_ref> == true); using r_ref = std::add_rvalue_reference_t<non_ref>; static_assert(std::is_rvalue_reference_v<r_ref> == true); using void_ref = std::add_lvalue_reference_t<void>; static_assert(std::is_reference_v<void_ref> == false); int main() {}
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 2101 | C++11 | Das Programm war fehlerhaft, wenn T ein Funktionstyp mit cv- oder ref-Qualifizierern war |
Der in diesem Fall erzeugte Typ ist T |
[bearbeiten] Siehe auch
| (C++11) |
prüft, ob ein Typ entweder eine lvalue-Referenz oder eine rvalue-Referenz ist (Klassenvorlage) |
| (C++11) |
entfernt eine Referenz vom gegebenen Typ (Klassenvorlage) |
| (C++20) |
kombiniert std::remove_cv und std::remove_reference (Klassenvorlage) |