繁体   English   中英

add_lvalue_reference_t 的区别<T>和T&

[英]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&&

Tcv voidT&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 = voidvoid& = 编译时错误

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM