Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove the const from 'char const*'

Tags:

c++

c++11

It appears that std::remove_const isn't able to remove the const-ness of const char*. 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();
}

Output of this program (on Visual Studio 2010):

char const *
char const *

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

PKc
PKc

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

like image 806
Uri Avatar asked Nov 20 '12 18:11

Uri


People also ask

How do I remove a const?

The statement int* c = const_cast<int>(b) returns a pointer c that refers to a without the const qualification of a . This process of using const_cast to remove the const qualification of an object is called casting away constness. Consequently the compiler does allow the function call f(c) .

Can you cast away const in C?

The compiler does allow the *c = 30 , but the behavior of this statement is undefined. If you cast away the constness of an object that has been explicitly declared as const , and attempt to modify it, the results are undefined.

What is const char * in CPP?

char* const says that the pointer can point to a char and value of char pointed by this pointer can be changed. But we cannot change the value of pointer as it is now constant and it cannot point to another char.

What is the difference between char and const char?

Simple: "char *name" name is a pointer to char, i.e. both can be change here. "const char *name" name is a pointer to const char i.e. pointer can change but not char.


1 Answers

char const* is a pointer to a const char, but the pointer itself is not const. To remove the constness from the type being pointed to, you could 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 const char, then remove const to get char, then add the pointer back to get char*. Not particularly pretty. To test:

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 outputs:

PKc
Pc

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

like image 159
Joseph Mansfield Avatar answered Oct 26 '22 23:10

Joseph Mansfield