How to remove a constant from 'char const *'

It looks like std :: remove_const cannot remove the const char* constant. Consider the following code:

 #include <iostream> #include <type_traits> #include <typeinfo> template< typename T > struct S { static void foo( ) { std::cout << typeid(T).name() << std::endl; std::cout << typeid( std::remove_const<T>::type ).name() << std::endl; } }; int main( ) { S<char const*>::foo(); } 

The output of this program (on Visual Studio 2010):

 char const * char const * 

And in gcc we have readable output (code here ):

 PKc PKc 

I would hope to get char * on the second line of the Microsoft compiler and anything (but different from the 1st line) on gcc. What am I doing wrong? How to turn char const* to char* ?

+4
source share
2 answers

If you want to remove all const qualifiers, you need a solution that recursively removes const from all levels:

 template<typename T> struct remove_all_const : std::remove_const<T> {}; template<typename T> struct remove_all_const<T*> { typedef typename remove_all_const<T>::type *type; }; template<typename T> struct remove_all_const<T * const> { typedef typename remove_all_const<T>::type *type; }; int main() { std::cout << typeid(remove_all_const<int const * * const>::type).name() << '\n'; } 
+6
source

char const* is a pointer to const char , but the pointer itself is not const . To remove a constant from a specified type, you can do this:

 std::add_pointer<typename std::remove_const<typename std::remove_pointer<T>::type>::type>::type 

Or alternatively:

 typename std::remove_const<typename std::remove_pointer<T>::type>::type* 

We remove the pointer from const char* to get a const char , then remove the const to get a char , then add the pointer back to get a char* . Not particularly beautiful. To check:

 typedef const char * type_before; std::cout << typeid(type_before).name() << std::endl; typedef typename std::remove_const<typename std::remove_pointer<type_before>::type>::type* type_after; std::cout << typeid(type_after).name() << std::endl; 

With g ++ on my system, this produces:

 PKc Pc 

This should give you a hint about what PKc means. P for pointer, c for char and K for konst ;)

+8
source

Source: https://habr.com/ru/post/1447302/


All Articles