std:: add_lvalue_reference, std:: add_rvalue_reference
From cppreference.net
C++
Metaprogramming library
| Type traits | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Compile-time rational arithmetic | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Compile-time integer sequences | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
(C++14)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
定义于头文件
<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]
|
|
如果程序对本页面描述的任何模板添加特化,则行为未定义。
目录 |
嵌套类型
| 名称 | 定义 |
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
|
参见
|
(C++11)
|
检查类型是否为
左值引用
或
右值引用
(类模板) |
|
(C++11)
|
从给定类型中移除引用
(类模板) |
|
(C++20)
|
结合
std::remove_cv
与
std::remove_reference
(类模板) |