Пространства имён
Варианты
Действия

std::add_lvalue_reference, std::add_rvalue_reference

Материал из cppreference.com
< cpp‎ | types
 
 
Библиотека метапрограммирования
Свойства типов
Категории типов
(C++11)
(C++14)  
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Свойства типов
(C++11)
(C++11)
(C++14)
(C++11)
(C++11)(до C++20*)
(C++11)(устарело в C++20)
(C++11)
Константы свойств типа
Метафункции
(C++17)
Поддерживаемые операции
Запросы отношений и свойств
Модификации типов
(C++11)(C++11)(C++11)
add_lvalue_referenceadd_rvalue_reference
(C++11)(C++11)

Преобразования типов
(C++11)(устарело в C++23)
(C++11)(устарело в C++23)
(C++11)
(C++11)
(C++17)

(C++11)(до C++20*)(C++17)
Рациональная арифметика времени компиляции
Целочисленные последовательности времени компиляции
 
Определено в заголовочном файле <type_traits>
template< class T >
struct add_lvalue_reference;
(1) (начиная с C++11)
template< class T >
struct add_rvalue_reference;
(2) (начиная с C++11)

Создаёт левостороннюю или правостороннюю ссылку на тип T.

1) Если T является функциональным типом, который не имеет cv- или ref-квалификатора, или объектным типом, предоставляет typedef элемент type, который равен T&. Если T является ссылкой rvalue на некоторый тип U, то type является U&. Иначе type равно T.
2) Если T является функциональным типом, который не имеет cv- или ref-квалификатора, или объектным типом, предоставляет typedef элемент type, который равен T&&, иначе type равно T.

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

Содержание

[править] Типы-элементы

Имя Определение
type ссылка на T, или T, если ссылку создать нельзя

[править] Вспомогательные типы

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)

[править] Примечание

Эти преобразования типов учитывают правила очистки ссылки:

  • std::add_lvalue_reference<T&>::type равно T&
  • std::add_lvalue_reference<T&&>::type равно T&
  • std::add_rvalue_reference<T&>::type равно T&
  • std::add_rvalue_reference<T&&>::type равно T&&

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

[править] Возможная реализация

namespace detail {
 
template <class T>
// или используйте std::type_identity (начиная с C++20)
struct type_identity { using type = T; };
 
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>
 
int main()
{
    using non_ref = int;
    using l_ref = typename std::add_lvalue_reference_t<non_ref>;
    using r_ref = typename std::add_rvalue_reference_t<non_ref>;
    using void_ref = std::add_lvalue_reference_t<void>;
 
    static_assert
        (  std::is_lvalue_reference_v<non_ref> == false
        && std::is_lvalue_reference_v<l_ref> == true
        && std::is_rvalue_reference_v<r_ref> == true
        && std::is_reference_v<void_ref> == false
        );
}

[править] Отчёты о дефектах

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

Номер Применён Поведение в стандарте Корректное поведение
LWG 2101 c++11 Эти свойства преобразования были необходимы для создания ссылок
на cv/ref квалифицированные функциональные типы.
Сами создают cv/ref квалифицированные
функциональные типы.

[править] Смотрите также

проверяет, является ли тип либо левосторонней ссылкой, либо правосторонней ссылкой
(шаблон класса) [править]
удаляет ссылку из данного типа
(шаблон класса) [править]
объединяет std::remove_cv и std::remove_reference
(шаблон класса) [править]