19

If I want to extract the type of a const reference (like double from const double&), do I have to use :

typename std::remove_cv<typename std::remove_reference<Type>::type>::type

or

typename std::remove_reference<typename std::remove_cv<Type>::type>::type

?

Vincent
  • 57,703
  • 61
  • 205
  • 388

2 Answers2

21

Use remove_reference first. remove_cv removes top level qualifiers only and in case of references, there isn't any (or is ignored).

An example that shows the difference:

#include <iostream>
#include <type_traits>

template<typename T>
using Remove_cv_ref = std::remove_cv<typename std::remove_reference<T>::type>;

template<typename T>
using Remove_ref_cv = std::remove_reference<typename std::remove_cv<T>::type>;

int main()
{
    std::cout << std::is_same<typename Remove_cv_ref<const int&>::type, int>::value; // 1
    std::cout << std::is_same<typename Remove_ref_cv<const int&>::type, int>::value; // 0
}

Live demo.

jrok
  • 54,456
  • 9
  • 109
  • 141
5
typename std::remove_cv<typename std::remove_reference<Type>::type>::type

because first remove_reference<const double&>::type is const double, then remove_cv<const double>::type is double.

But if you have C++11, have a look at std::decay.

gx_
  • 4,690
  • 24
  • 31
  • 8
    `std::decay` != [`Unqualified`](http://flamingdangerzone.com/cxx11/2013/02/25/even-more-traits.html#unqualified_types), the two imply different semantics. – Xeo Jun 25 '13 at 10:58
  • 2
    @Xeo Yes you are right. (But when `T` is neither a function nor an array (which was the case for `const double&`) then `decay::type` is the same as `remove_cv::type>::type`.) (Also I said "have a look at", not "use rather" ^^) – gx_ Jun 25 '13 at 12:24