Почему `std :: add_pointer`, добавляет ранее удаленный` const`? - PullRequest
0 голосов
/ 05 января 2020

Извинения, если название немного вводит в заблуждение. Вот ситуация.

Рассмотрим следующий пример:

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>
}

Тип: int const *

Сейчас Когда я удаляю часть const *, используя std::remove_pointer, а я использую std::add_pointer, чтобы добавить указатель обратно без 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::add_pointer<rp_Type>::type p_Type;    // int const *  <???>

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

Чтобы получить указатель без const Мне нужно использовать std::remove_const. Но зачем это нужно, поскольку std::remove_pointer уже удалил 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>
}

Пример кода онлайн: https://rextester.com/YYE94945

Ответы [ 2 ]

2 голосов
/ 05 января 2020

Ваш demangle_typename здесь не подходит для цели: он не покажет вам верхнего уровня const, поэтому ваши результаты не являются правильными наблюдениями. ( Однако это можно исправить! )

rp_Type - это не int, а const int.

Удаление слоя указателя не приводит к удалению константы.

То есть const не «добавлено»; это никогда не было фактически удалено. Вы просто не наблюдаете это с вашим решением, когда оно на высшем уровне.

2 голосов
/ 05 января 2020

typeid отбрасывает cv-квалификаторы верхнего уровня для типов. Он не видит никакой разницы между int и const int.

std::remove_pointer_t<const int *> равен const int, а не int, но const не печатается из-за этого.

...