Reputation: 2732
How can I remove all const qualifiers from a data type?
I tried to use std::remove_cv
but it didnt work.
std::remove_cv< const char *>::type
Isn't it the same as std::remove_cv<char*>::type
?
Thanks.
Upvotes: 1
Views: 3267
Reputation: 40613
There isn't a standard way to do this, you will need to write your own:
template<typename T> struct remove_const_recursive { typedef T type; };
template<typename T> struct remove_const_recursive<T const volatile> {
typedef typename remove_const_recursive<T>::type volatile type;
};
template<typename T> struct remove_const_recursive<T volatile> {
typedef typename remove_const_recursive<T>::type volatile type;
};
template<typename T> struct remove_const_recursive<T const> {
typedef typename remove_const_recursive<T>::type type;
};
template<typename T> struct remove_const_recursive<T&> {
typedef typename remove_const_recursive<T>::type& type;
};
template<typename T> struct remove_const_recursive<T*> {
typedef typename remove_const_recursive<T>::type* type;
};
Upvotes: 1
Reputation: 74018
You can see the differences between a constant pointer and a pointer pointing to const and the various type_traits
with
#include <iostream>
#include <type_traits>
int main()
{
std::cout << std::is_same<std::remove_const<const char*>::type, char*>::value << '\n';
std::cout << std::is_same<std::remove_const<char* const>::type, char*>::value << '\n';
std::cout << std::is_same<std::add_pointer<std::remove_const<std::remove_pointer<const char*>::type>::type>::type, char*>::value << '\n';
return 0;
}
which gives as output
0
1
1
Upvotes: 0
Reputation: 545518
The trait is doing everything correctly:
const char*
is the same as char const*
and neither is the same as char* const
. So in your case, it’s the pointee that’s const
, not the pointer. And remove_const
(somewhat logically) only removes the outer const
, not inner ones.
If you really want to remove the const
ness of the pointee, you can do it like this:
using T = char const*;
using NoConstT = std::add_pointer<std::remove_cv<std::remove_pointer<T>::type>::type>::type;
(Although std::add_pointer<T>::type
could be dropped in favour of the simpler T*
…)
That is: remove the pointer, remove the const
of the pointee, make the result a pointer again.
In fact, this is a good opportunity to use use R. Martinho Fernandes’ excellent Wheels library which provides convenient shortcuts for such nested traits:
#include <wheels/meta.h++>
using namespace wheels;
…
using NoConstT = AddPointer<RemoveCv<RemovePointer<T>>>;
Much more readable.
Upvotes: 5
Reputation: 275240
Do it recursively. Match T*
in a specialization, then reapply the *
, etc.
Upvotes: 0