简体   繁体   中英

Why does `std::add_pointer`, adds a previously removed `const`?

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM