Стандартный C++11 способ удалить все указатели типа

Есть ли способ сделать это с помощью некоторого C++11 или, в лучшем случае, библиотеки boost?

#include <iostream>
#include <typeinfo>
using namespace std;

template <typename T> class remove_all_pointers{
public:
    typedef T type;
};

template <typename T> class remove_all_pointers<T*>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

int main(){
    //correctly prints 'i' on gcc
    cout<<typeid(remove_all_pointers<int****>::type).name()<<endl;
}

3 ответа

Решение

Ни Boost, ни C++11 не имеют такого шаблона черты. Но ваш код должен работать.

Это не совсем работает для всех типов указателей. Вам также необходимо учитывать различные cv-квалификаторы:

template <typename T> class remove_all_pointers<T* const>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

template <typename T> class remove_all_pointers<T* volatile>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

template <typename T> class remove_all_pointers<T* const volatile >{
public:
    typedef typename remove_all_pointers<T>::type type;
};

В C++17 мета-функция, удобная для чтения и использования cv-квалификатора:

#include <type_traits>

// unfortunately there's no std::identity anymore in C++17
template <typename T>
struct identity
{
    using type = T;
};

template<typename T>
struct remove_all_pointers : std::conditional_t<
    std::is_pointer_v<T>,
    remove_all_pointers<
        std::remove_pointer_t<T>
    >,
    identity<T>
>
{};

template<typename T>
using remove_all_pointers_t = typename remove_all_pointers<T>::type;

Тогда используйте это как:

int main()
{
    remove_all_pointers_t<int* const* volatile* const volatile*> v = 42;
    return 0;
}
Другие вопросы по тегам