std:: add_lvalue_reference, std:: add_rvalue_reference
| Type traits | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Compile-time rational arithmetic | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Compile-time integer sequences | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
(C++14)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Definido en el encabezado
<type_traits>
|
||
|
template
<
class
T
>
struct add_lvalue_reference ; |
(1) | (desde C++11) |
|
template
<
class
T
>
struct add_rvalue_reference ; |
(2) | (desde C++11) |
Crea un tipo de referencia lvalue o rvalue de
T
.
| Rasgo de tipo |
El tipo referido por el tipo anidado
type
|
|
|---|---|---|
T
es un
tipo referenciable
|
T
no es un tipo referenciable
|
|
| (1) |
T&
[1]
|
T
|
| (2) |
T&&
[2]
|
|
- ↑ Esta regla refleja la semántica de reference collapsing .
-
↑
Esta regla refleja la semántica de
reference collapsing
. Nótese que
std
::
add_rvalue_reference
<
T
&
>
::
type
es
T&, que no es un tipo de referencia a valor-R.
Si el programa añade especializaciones para cualquiera de las plantillas descritas en esta página, el comportamiento es indefinido.
Contenidos |
Tipos anidados
| Nombre | Definición |
type
|
determinado como arriba |
Tipos auxiliares
|
template
<
class
T
>
using add_lvalue_reference_t = typename add_lvalue_reference < T > :: type ; |
(desde C++14) | |
|
template
<
class
T
>
using add_rvalue_reference_t = typename add_rvalue_reference < T > :: type ; |
(desde C++14) | |
Notas
La principal diferencia con el uso directo de
T&
o
T&&
es que
T
puede ser un tipo
no referenciable
. Por ejemplo,
std
::
add_lvalue_reference
<
void
>
::
type
es
void
, mientras que
void
&
produce un error de compilación.
Implementación posible
namespace detail { template<class T> struct type_identity { using type = T; }; // o usar std::type_identity (desde C++20) template<class T> // Nótese que "cv void&" es un fallo de sustitución auto try_add_lvalue_reference(int) -> type_identity<T&>; template<class T> // Manejar caso T = cv void 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)) {}; |
Ejemplo
#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() {}
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 2101 | C++11 |
el programa estaba mal formado si
T
es un
tipo función
con
cv
o
ref
|
el tipo producido es
T
en este caso
|
Véase también
|
(C++11)
|
comprueba si un tipo es una
referencia lvalue
o una
referencia rvalue
(plantilla de clase) |
|
(C++11)
|
elimina una referencia del tipo dado
(plantilla de clase) |
|
(C++20)
|
combina
std::remove_cv
y
std::remove_reference
(plantilla de clase) |