Стандартный 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;
}