0

Apologies if the title is a bit misleading.. Here's the situation.

Consider the following example:

template<typename T>
static std::string demangle_typename()
{
    int status = 0;
    return abi::__cxa_demangle(typeid(T).name(),nullptr,nullptr,&status);
}

void foo()
{  
    typedef const int* Type;
    std::cout<< demangle_typename<Type>() <<std::endl;   // type is: int const *  <ok>
}

The type is int const *

Now, when I remove the const * part using std::remove_pointer and the I use std::add_pointer to add the pointer back without the const, the constness reappears. Why?

void foo()
{  
    typedef const int* Type;
    std::cout<< demangle_typename<Type>() <<std::endl;   // type is: int const *  <ok>

    typedef typename std::remove_pointer<Type>::type rp_Type;   // int
    typedef typename std::add_pointer<rp_Type>::type p_Type;    // int const *  <???>

    std::cout<< demangle_typename<p_Type>() <<std::endl;   // type is: int const *  <???>
}

To get the pointer without the const I need to use std::remove_const. But why is this needed, since std::remove_pointer has already removed the const?

void foo()
{  
    typedef const int* Type;
    std::cout<< demangle_typename<Type>() <<std::endl;   // type is: int const *  <ok>

    typedef typename std::remove_pointer<Type>::type rp_Type;  // int
    typedef typename std::remove_const<rp_Type>::type rc_Type; // int
    typedef typename std::add_pointer<rc_Type>::type p_Type;   // int*

    std::cout<< demangle_typename<p_Type>() <<std::endl;   // type is: int*  <ok>
}

Online code example: https://rextester.com/YYE94945

Constantinos Glynos
  • 2,952
  • 2
  • 14
  • 32
  • @LightnessRacesBY-SA3.0: It's what I got from the online compiler... I'll switch to boost because according to one of the answers, `typeid` discard top-level cv qualifiers. – Constantinos Glynos Jan 05 '20 at 19:30
  • See the link in my answer for better approaches for examining type. This problem is explicitly discussed there too. You don't need Boost. – Lightness Races in Orbit Jan 05 '20 at 19:30
  • @ConstantinosGlynos Just curious, what are planning to use boost for? There's something in it that prints type names? – HolyBlackCat Jan 05 '20 at 19:32

2 Answers2

2

typeid discards top-level cv-qualifiers on types. It doesn't see any difference between int and const int.

std::remove_pointer_t<const int *> is const int rather than int, but const doesn't get printed because of that.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • How come it doesn't show up then and it prints out just `int`? Also, according to the online documentation [here](https://en.cppreference.com/w/cpp/types/remove_pointer), `std::remove_pointer` should remove both the constness and the pointer. It says: `template< class T > struct remove_pointer {typedef T type;};` – Constantinos Glynos Jan 05 '20 at 19:18
  • @ConstantinosGlynos Because `typeid` ignores any top-level cv-qualifiers on the type. It doesn't see any difference between `int` and `const int`. (I'll clarify the answer.) *"should remove both the constness and the pointer"* In this snippet the `const` is to the right of `*` ("const pointer to T"). So the pointer itself is `const`, and this constness is removed along with `*`. In the question you have `const` to the left of `*` ("non-const pointer to const int"), so the pointer itself is not `const`. – HolyBlackCat Jan 05 '20 at 19:20
  • Oh I see! The specialization of `std::remove_pointer` refers to a `int * const`, not a `const int *`. I got confused with the type not showing up. I should have used boost to avoid this confusion! Thanks. – Constantinos Glynos Jan 05 '20 at 19:29
2

Your demangle_typename is not fit for purpose here: it won't show you top-level const, so your results are not correct observations. (It can be fixed, though!)

rp_Type is not int but const int.

Removing a pointer layer does not remove pointee constness.

So the const is not "added"; it was never actually removed. You just don't observe it, with your solution, when it's top-level.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055