Namespaces
Variants

std:: add_lvalue_reference, std:: add_rvalue_reference

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
(C++17)
Supported operations
Relationships and property queries
Type modifications
add_lvalue_reference add_rvalue_reference
(C++11) (C++11)

Type transformations
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

Compile-time rational arithmetic
Compile-time integer sequences
Определено в заголовочном файле <type_traits>
template < class T >
struct add_lvalue_reference ;
(1) (начиная с C++11)
template < class T >
struct add_rvalue_reference ;
(2) (начиная с C++11)

Создает ссылочный тип lvalue или rvalue для T .

Характеристика типа Тип, на который ссылается вложенный тип type
T является ссылочным типом T не является ссылочным типом
(1) T& [1] T
(2) T&& [2]
  1. Это правило отражает семантику схлопывания ссылок .
  2. Это правило отражает семантику схлопывания ссылок . Заметьте, что std :: add_rvalue_reference < T & > :: type является T& , что не является типом rvalue-ссылки.

Если программа добавляет специализации для любых шаблонов, описанных на этой странице, поведение не определено.

Содержание

Вложенные типы

Название Определение
type определяется как указано выше

Вспомогательные типы

template < class T >
using add_lvalue_reference_t = typename add_lvalue_reference < T > :: type ;
(начиная с C++14)
template < class T >
using add_rvalue_reference_t = typename add_rvalue_reference < T > :: type ;
(начиная с C++14)

Примечания

Основное отличие от прямого использования T& или T&& заключается в том, что T может быть нессылочным типом. Например, std :: add_lvalue_reference < void > :: type является void , тогда как void & приводит к ошибке компиляции.

Возможная реализация

namespace detail
{
    template<class T>
    struct type_identity { using type = T; }; // или использовать std::type_identity (начиная с C++20)
    template<class T> // Заметим, что "cv void&" приводит к ошибке подстановки
    auto try_add_lvalue_reference(int) -> type_identity<T&>;
    template<class T> // Обрабатывает случай 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)) {};

Пример

#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() {}

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
LWG 2101 C++11 программа была некорректна, если T является типом функции с cv или ref в этом случае создаваемый тип - T

Смотрите также

проверяет, является ли тип lvalue reference или rvalue reference
(class template)
удаляет ссылку из заданного типа
(class template)
объединяет std::remove_cv и std::remove_reference
(class template)