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 起)

创建 T 类型的左值或右值引用。

类型特征 嵌套类型 type 所指代的类型
T 是可引用类型时 T 不是可引用类型时
(1) T& [1] T
(2) T&& [2]
  1. 该规则反映了 引用折叠 的语义。
  2. 该规则反映了 引用折叠 的语义。注意 std :: add_rvalue_reference < T & > :: type T& ,而非右值引用类型。

如果程序对本页面描述的任何模板添加特化,则行为未定义。

目录

嵌套类型

名称 定义
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++标准。

缺陷报告 应用于 发布时行为 正确行为
LWG 2101 C++11 T 是带有 cv ref 函数类型 时程序非良构 此种情况下生成的类型为 T

参见

检查类型是否为 左值引用 右值引用
(类模板)
从给定类型中移除引用
(类模板)
结合 std::remove_cv std::remove_reference
(类模板)