Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11: extending std::is_pointer to std::shared_ptr

I think about overloading std::is_pointer in C++11 to yield true for std::shared_ptr<T> as well, since the latter behaves very much as a T*.

#include <type_traits>

namespace std {

template <typename T> struct is_pointer<shared_ptr<T>> : std::true_type {};
template <typename T> struct is_pointer<shared_ptr<T const>> : std::true_type {};

}

I wonder why this overload has not already been included in the standard implementation. Is there a pitfall that I'm overlooking?

As an alternative one could of course introduce a new trait is_shared_ptr<T>.

Actually, I tried the following code in the first place:

template <typename T> 
struct is_pointer<shared_ptr<typename std::remove_cv<T>::type>>
  : std::true_type 
{};

which does not compile with GCC 4.7 due to

error: template parameters not used in partial specialization:
error:         ‘T’
like image 548
Erwin411 Avatar asked Jun 12 '13 12:06

Erwin411


1 Answers

std::is_pointer somehow comes from Boost and is originally meant to detect raw pointers and function pointers only, here is the bottom note you can find in Boost documentation:

is_pointer detects "real" pointer types only, and not smart pointers. Users should not specialise is_pointer for smart pointer types, as doing so may cause Boost (and other third party) code to fail to function correctly. Users wanting a trait to detect smart pointers should create their own. However, note that there is no way in general to auto-magically detect smart pointer types, so such a trait would have to be partially specialised for each supported smart pointer type.

They probably just had it behave like that in the standard library for compatibility to keep a low level of surprise for users that already used it. Anyway, as you just demonstrated it, it is easy to create your own trait to detect smart pointers.

Basically, what you are looking would be a trait that would look for types which implement the Dereferenceable concept (even though this one would also work for std::optional and not only pointers/smart pointers).

And for the sake of completeness, Boost's is_pointer design is there to detect only raw pointers and not pointer-like classes. But the other answers should already give you some pretty good information about that.

like image 167
Morwenn Avatar answered Sep 29 '22 14:09

Morwenn