std::add_lvalue_reference, std::add_rvalue_reference
来自cppreference.com
| 在标头 <type_traits> 定义
|
||
| |
(1) | (C++11 起) |
| |
(2) | (C++11 起) |
创建 T 的左值或右值引用类型。
1) 如果
T 是一个没有 cv 或引用限定符的函数类型,或者是一个对象类型,则提供成员 typedef type,其类型为 T&。如果 T 是某个类型 U 的右值引用,则 type 为 U&。否则,type 为 T。2) 如果
T 是一个没有 cv 或引用限定符的函数类型,或者是一个对象类型,则提供成员 typedef type,其类型为 T&&,否则 type 为 T。如果程序添加了此页面上描述的任何模板的特化,那么行为未定义。
成员类型
| 名字 | 定义 |
type
|
T 的引用,或当“T 的引用”无效时为 T
|
辅助类型
| |
(C++14 起) | |
| |
(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>
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>
int main()
{
using non_ref = int;
using l_ref = typename std::add_lvalue_reference_t<non_ref>;
static_assert(std::is_lvalue_reference_v<l_ref>);
using r_ref = typename std::add_rvalue_reference_t<non_ref>;
static_assert(std::is_rvalue_reference_v<r_ref>);
using void_ref = std::add_lvalue_reference_t<void>;
static_assert(!std::is_reference_v<void_ref>);
}
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| 缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
|---|---|---|---|
| LWG 2101 | C++11 | 规定这些变换特征 产生对 cv/引用限定的函数类型的引用。 |
产生 cv/引用限定的函数类型自身。 |
参阅
(C++11) |
检查类型是否为左值引用 或右值引用 (类模板) |
(C++11) |
从给定类型移除引用 (类模板) |
(C++20) |
将 std::remove_cv 与 std::remove_reference 结合 (类模板) |