std:: add_lvalue_reference, std:: add_rvalue_reference
|
Definiert im Header
<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
.
| Type-Trait |
Der durch den geschachtelten Typ
type
referenzierte Typ
|
|
|---|---|---|
T
ist ein
referenzierbarer Typ
|
T
ist kein referenzierbarer Typ
|
|
| (1) |
T&
[1]
|
T
|
| (2) |
T&&
[2]
|
|
- ↑ Diese Regel spiegelt die Semantik von Reference Collapsing wider.
-
↑
Diese Regel spiegelt die Semantik von
Reference Collapsing
wider. Beachten Sie, dass
std
::
add_rvalue_reference
<
T
&
>
::
type
T&ist, was kein Rvalue-Referenztyp ist.
Wenn das Programm Spezialisierungen für irgendeine der auf dieser Seite beschriebenen Templates hinzufügt, ist das Verhalten undefiniert.
Inhaltsverzeichnis |
Verschachtelte Typen
| Name | Definition |
type
|
wie oben bestimmt |
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) | |
Hinweise
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
void
, während
void
&
zu einem Kompilierungsfehler führt.
Mögliche Implementierung
namespace detail { template<class T> struct type_identity { using type = T; }; // oder verwende std::type_identity (seit C++20) template<class T> // Beachte, dass „cv void&“ ein Substitutionsfehler ist auto try_add_lvalue_reference(int) -> type_identity<T&>; template<class T> // Behandelt T = cv void Fall 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)) {}; |
Beispiel
#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() {}
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 2101 | C++11 |
das Programm war fehlerhaft, wenn
T
ein
Funktionstyp
mit
cv
oder
ref
ist
|
der erzeugte Typ ist in diesem Fall
T
|
Siehe auch
|
(C++11)
|
prüft, ob ein Typ entweder ein
lvalue reference
oder
rvalue reference
ist
(Klassentemplate) |
|
(C++11)
|
entfernt eine Referenz vom gegebenen Typ
(Klassentemplate) |
|
(C++20)
|
kombiniert
std::remove_cv
und
std::remove_reference
(Klassentemplate) |