table of contents
        
      
      
    | std::add_lvalue_reference,std::add_rvalue_reference(3) | C++ Standard Libary | std::add_lvalue_reference,std::add_rvalue_reference(3) | 
NAME¶
std::add_lvalue_reference,std::add_rvalue_reference - std::add_lvalue_reference,std::add_rvalue_reference
Synopsis¶
 Defined in header <type_traits>
  
   template< class T > (1) (since C++11)
  
   struct add_lvalue_reference;
  
   template< class T > (2) (since C++11)
  
   struct add_rvalue_reference;
  
   Creates an lvalue or rvalue reference type of T.
  
   Type trait The type referred by the nested type type
  
   T is a referenceable type T is not a referenceable type
  
   (1) T&^[1] T
  
   (2) T&&^[2]
  
   1. ↑ This rule reflects the semantics of reference collapsing.
  
   2. ↑ This rule reflects the semantics of reference collapsing. Note
    that
  
   std::add_rvalue_reference<T&>::type is T&, which is not an
    rvalue reference
  
   type.
  
   If the program adds specializations for any of the templates described on
    this page,
  
   the behavior is undefined.
Helper types¶
 template< class T >
  
   using add_lvalue_reference_t = typename (since C++14)
  
   add_lvalue_reference<T>::type;
  
   template< class T >
  
   using add_rvalue_reference_t = typename (since C++14)
  
   add_rvalue_reference<T>::type;
Notes¶
 The major difference to directly using T& or T&& is
    that T can be a
  
   non-referenceable type. For example,
    std::add_lvalue_reference<void>::type is void,
  
   while void& leads to a compilation error.
Possible implementation¶
 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)) {};
Example¶
// Run this code
  
   #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() {}
  
   Defect reports
  
   The following behavior-changing defect reports were applied retroactively to
  
   previously published C++ standards.
  
   DR Applied to Behavior as published Correct behavior
  
   LWG 2101 C++11 the program was ill-formed if T is a the type produced is T in
  
   function type with cv or ref this case
See also¶
 is_reference checks if a type is either an lvalue reference or
    rvalue reference
  
   (C++11) (class template)
  
   remove_reference removes a reference from the given type
  
   (C++11) (class template)
  
   remove_cvref combines std::remove_cv and std::remove_reference
  
   (C++20) (class template)
| 2024.06.10 | http://cppreference.com |