Since C++17 you can create a readable, simple and cv-qualifier aware meta function.
Use it like:
int main()
{
remove_all_pointers_t<int* const* volatile* const volatile*> v = 42;
return 0;
}
C++20
#include <type_traits>
template<typename T>
struct remove_all_pointers : std::conditional_t<
std::is_pointer_v<T>,
remove_all_pointers<
std::remove_pointer_t<T>
>,
std::type_identity<T>
>
{};
template<typename T>
using remove_all_pointers_t = typename remove_all_pointers<T>::type;
C++17
In C++17 std::type_identity
isn't available yet and std::identity
isn't available anymore, hence you need to create your own 'identity' meta function:
#include <type_traits>
// your custom 'identity' meta function
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;