add_lvalue_reference_t<T> 和 T& 之间的区别
Posted
技术标签:
【中文标题】add_lvalue_reference_t<T> 和 T& 之间的区别【英文标题】:Difference between add_lvalue_reference_t<T> and T& 【发布时间】:2015-08-21 18:37:25 【问题描述】:假设您有一个模板参数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&&
。什么时候选哪个有什么规定吗?
【问题讨论】:
【参考方案1】: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&
和 T&&
当 T
是 cv void
时格式不正确,但这些模板格式正确,只是返回原始类型。
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>
会给出一个指向参数实际类型的指针。
【讨论】:
【参考方案2】:根据我在 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*
【讨论】:
有趣,为什么要否决这个答案? 编译时错误不确定。在某些实现中不会发生错误【参考方案3】:在大多数情况下,std::add_rvalue_reference_t<T>
等同于 T&&
。但是,reference collapsing rules 和 the-rules-that-dictate-which-types-are-referenceable 如果不加以考虑,可能会使您的代码行为不端。
但是,由于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>
之类的东西通常在操作类型的引用属性时更常用。
【讨论】:
最好说“可能”而不是断言可能(不知何故)不是这样的事情。这背后的要点和“他/她的意见”是 OP 没有具体说明他/她在做什么(或者更确切地说,为什么)。是简单的理论吗?或者更确切地说,正如我所说的,“黑魔法”?我们不知道,参考折叠规则会在很大程度上影响他/她的代码是否行为不端(如果不考虑的话)。 顺便说一句,我再次编辑。在之前的编辑中,第一段变得毫无意义,所以@Barry 有他的观点。 别名模板如何影响参考折叠? 您可能的意思是“引用折叠如何影响别名模板?”,它本身应该改写为“引用折叠如何影响模板?”。嗯,答案有点复杂,应该在另一个问题上解决。以上是关于add_lvalue_reference_t<T> 和 T& 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章
X-005 FriendlyARM tiny4412 uboot移植之时钟初始化
X-004 FriendlyARM tiny4412 uboot移植之点亮指路灯
X-003 FriendlyARM tiny4412 uboot移植之添加相应目录文件