std::add_lv...ue_reference(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

bestie, welcome to the C++ Standard Libary manual, section 3 πŸ˜­πŸ’… β€” this page is std::add_lv...ue_reference(3), and it's all about the type-trait twins std::add_lvalue_reference and std::add_rvalue_reference. No cap, they're lowkey iconic.


✨ NAME ✨

  • std::add_lvalue_reference,std::add_rvalue_reference β€” the two type traits this page covers. The original NAME line is literally that pair, no extra lore πŸŽ€

πŸ¦‹ 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. Periodt.

Here's the vibe check on what the nested type ends up being:

  • Type trait (1) β€” if T is a referenceable type, the nested type is T&^[1]; if T is not a referenceable type, it's T.
  • Type trait (2) β€” if T is a referenceable type, the nested type is T&&^[2]; if T is not a referenceable type, it's T.

^[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. πŸ’€ So don't do that, bestie.

πŸŽ€ Helper types πŸŽ€

template< class T >
using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;

(since C++14)

template< class T >
using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;

(since C++14)

🌸 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. Not me finding that out the hard way πŸ˜­πŸ’€

🧚 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, bestie:

#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 LWG 2101 β€” applied to C++11. Behavior as published: the program was ill-formed if T is a function type with cv or ref. Correct behavior: the type produced is T in this case.

⭐ See also ⭐

  • is_reference (C++11) β€” checks if a type is either an lvalue reference or rvalue reference (class template)
  • remove_reference (C++11) β€” removes a reference from the given type (class template)
  • remove_cvref (C++20) β€” combines std::remove_cv and std::remove_reference (class template)

source: http://cppreference.com Β· version/date: 2024.06.10 Β· page: std::add_lv...ue_reference(3) πŸ’–βœ¨ That's the whole manual page, bestie β€” go forth and reference responsibly 🫢

πŸ“¦ where this page comes from