[英]Difference between add_lvalue_reference_t<T> and T&
假设您有一个模板参数T
。
之间有什么区别
add_cv_t<T>
和const volatile T
add_const_t<T>
和const T
add_volatile_t<T>
和volatile T
add_lvalue_reference_t<T>
和T&
add_rvalue_reference_t<T>
和T&&
add_pointer_t<T>
和T*
? 例如,为什么我应该使用add_rvalue_reference_t<T>
而不是T&&
。 什么时候选择哪个有什么规则吗?
add_cv_t<T>
和const volatile T
add_const_t<T>
和const T
add_volatile_t<T>
和volatile T
没有不同; 例如, add_const<T>::type
的定义就是T const
。
add_lvalue_reference_t<T>
和T&
add_rvalue_reference_t<T>
和T&&
当T
为cv void
, T&
和T&&
格式错误,但这些模板格式良好,只是返回原始类型。
add_pointer_t<T>
和T*
?
add_pointer_t<T>
等价于std::remove_reference<T>::type*
。 也就是说,如果T
是一个引用类型,它会给出一个指向被引用类型的指针。 另一方面, T*
将是格式错误的,因为您无法拥有指向引用的指针。
你应该使用哪个?
T
。 当然,这意味着如果你想要扣除,你应该避免它们。T*
等替代品不同的别名模板在通用代码中很有用,因为它们“做正确的事”。 例如,如果T
是从T&&
类型的参数推导出来的,那么当参数是左值时T*
会做错事,因为它试图声明一个指向左值引用的指针。 但是std::add_pointer_t<T>
会给出一个指向参数实际类型的指针。根据我在 STL 源中看到的内容:
add_cv_t<T>
和const volatile T
- 没有区别
add_const_t<T>
和const T
- 没有区别
add_volatile_t<T>
和volatile T
- 没有区别
add_lvalue_reference_t<T>
和T&
- 例如,如果 T 是不可引用的类型 void,则存在差异。 add_lvalue_reference_t<void>::type = void
和void&
= 编译时错误
add_rvalue_reference_t<T>
和T&&
- 同上
add_pointer_t<T>
和T*
- T 是引用时的区别,因为没有引用指针这样的东西。 add_pointer_t<T>
等价于std::remove_reference<T>::type*
在大多数情况下, std::add_rvalue_reference_t<T>
等价于T&&
。 但是,如果不考虑 引用折叠规则和指示哪些类型可 引用的规则,则可能会使您的代码行为不端。
但是,在某些情况下,由于T
是不可引用的类型,因此type
静态成员类型会有所不同。 例如std::add_rvalue_reference_t<void>
解析为void
,并且(以您提到的另一个模板为例) std::add_pointer_t<T&>
解析为T*
(如果您想调用混乱,所需的仪式是std::add_pointer_t<std::add_rvalue_reference_t<void>>
:))
就用途而言,它可以用作模板模板参数来做一些时髦的黑魔法。 无论如何,在操作类型的引用属性时,通常更常用std::is_rvalue_reference_t<T>
或std::remove_reference_t<T>
之类的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.