Reputation: 14623
I'm having difficulty with types, such as:
T******************************************
Should std::remove_pointer
be able to handle such types at all (I don't think so)? How to remove all the *
? If there is an ampersand &
or two added at the end, does there exist a metafunction from the C++11
standard to strip such a type down to T
without using both the std::remove_reference
and std::remove_pointer
metafunctions?
Upvotes: 1
Views: 864
Reputation: 56118
It's not too hard to write a meta-function that will return return the base type no matter how many *
s and &
s you have.
template <typename T>
struct remove_all_ref_ptr { typedef T type; };
template <typename T>
struct remove_all_ref_ptr<T *> : public remove_all_ref_ptr<T> { };
template <typename T>
struct remove_all_ref_ptr<T * const> : public remove_all_ref_ptr<T> { };
template <typename T>
struct remove_all_ref_ptr<T * volatile> : public remove_all_ref_ptr<T> { };
template <typename T>
struct remove_all_ref_ptr<T * const volatile> : public remove_all_ref_ptr<T> { };
template <typename T>
struct remove_all_ref_ptr<T &> : public remove_all_ref_ptr<T> { };
template <typename T>
struct remove_all_ref_ptr<T &&> : public remove_all_ref_ptr<T> { };
And ::std::remove_pointer
can handle types like that just fine. It just lops off a single *
.
The little meta-function I just wrote will run into the recursion depth limit eventually. But you'll likely have to put on more than a hundred *
s to make that happen.
Here is how you might use it in conjunction with a standard library meta-function to remove the const and volatile qualifiers as well:
#include <type_traits>
template <typename T>
struct base_type : public ::std::remove_cv<typename remove_all_ref_ptr<T>::type> { };
Upvotes: 10