10

Suppose you have a template argument T.

What are the differences between

  • add_cv_t<T> and const volatile T
  • add_const_t<T> and const T
  • add_volatile_t<T> and volatile T
  • add_lvalue_reference_t<T> and T&
  • add_rvalue_reference_t<T> and T&&
  • add_pointer_t<T> and T*?

Why should I use add_rvalue_reference_t<T> instead of T&& for example. Are there any rules when to choose which?

Uroc327
  • 1,379
  • 2
  • 10
  • 28

3 Answers3

14
  • add_cv_t<T> and const volatile T
  • add_const_t<T> and const T
  • add_volatile_t<T> and volatile T

No difference; the definition of add_const<T>::type is just T const, for example.

  • add_lvalue_reference_t<T> and T&
  • add_rvalue_reference_t<T> and T&&

T& and T&& are ill-formed when T is cv void, but these templates are well-formed, just giving the original type back.

  • add_pointer_t<T> and T*?

add_pointer_t<T> is equivalent to std::remove_reference<T>::type*. That is, if T is a reference type, it gives a pointer to the referenced type. On the other hand, T* will be ill-formed since you cannot have a pointer to a reference.

Which should you use?

  • In general, the alias templates can be used to prevent deduction of T. Of course, that means that if you want deduction, you should avoid them.
  • The alias templates can be used as template template arguments to a template that takes a type transformation as a parameter.
  • The alias templates that differ in behaviour from alternatives like T* are useful in generic code since they "do the right thing". For example, if T is deduced from an argument of type T&&, then T* does the wrong thing when the argument is an lvalue, since it tries to declare a pointer to an lvalue reference. But std::add_pointer_t<T> will give a pointer to the actual type of the argument.
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
4

According to what I see in STL source:

add_cv_t<T> and const volatile T- no difference

add_const_t<T> and const T - no difference

add_volatile_t<T> and volatile T - no difference

add_lvalue_reference_t<T> and T& - there is difference for example if T is non referenceable type void. add_lvalue_reference_t<void>::type = void and void& = compile-time error

add_rvalue_reference_t<T> and T&& - the same as above

add_pointer_t<T> and T* - difference when T is reference, because there is no such thing as pointer to reference. add_pointer_t<T> is equivalent to std::remove_reference<T>::type*

Elohim Meth
  • 1,777
  • 9
  • 13
0

In most cases, std::add_rvalue_reference_t<T> is equivalent to T&&. However, reference collapsing rules and the-rules-that-dictate-which-types-are-referenceable may have your code misbehave if not taked into account.

There are, however, some cases where the type static member type will be different due to T being a non-referenceable type. For example std::add_rvalue_reference_t<void> resolves to void, and (taking another template you mentioned as an example) std::add_pointer_t<T&> resolves to T* (if you want to invoke chaos, the required ritual is std::add_pointer_t<std::add_rvalue_reference_t<void>> :))

Respecting to uses, it may be used as a template template parameter to do some funky black magic. Anyway, stuff like std::is_rvalue_reference_t<T> or std::remove_reference_t<T> is usually more commonly used when manipulating the type's reference attributes.

3442
  • 8,248
  • 2
  • 19
  • 41
  • It's simply better to say "probably" rather to assert something that may (somehow) not be the case. The point behind that and "his/her opinion", is that the OP isn't specifing what (or rather, *why*) is he/she doing it. Is it simple theory? Or rather, as I call it, "black magic"? We don't know, and reference collapsing rules can pretty much affect whether his/her code misbehaves (if not taken into account). – 3442 Aug 21 '15 at 19:24
  • BTW, I edited again. With the previous edit, the first paragraph became non-sense, and so @Barry had his point with it. – 3442 Aug 21 '15 at 19:26
  • How do alias templates affect reference collapsing? – Uroc327 Aug 21 '15 at 20:58
  • You probably meant "how do reference collapsing affect alias templating?", which at its own should be rephrased to "how do reference collapsing affect templates?". Well, the answer is a bit complex and should be addressed on another question. – 3442 Aug 21 '15 at 22:21