(For background info, it might help to read shared_ptr without RTTI? first. Or it might not.)
I'm looking at the interface for shared_ptr
out of curiosity — that is, this question is not motivated by a real use-case, but just questioning whether I'm missing something. I see that shared_ptr
does type-erasure of its deleter, similarly to std::any
and std::function
. In the latter two cases the Standard always gives us a pair of type-unerasure functions: one that tells the exact typeid
of the erased object, and one that reveals the original object iff we can guess its original type at compile time (and if not, "go fish!").
int xx = 42;
using Type = decltype(xx);
std::any a = xx;
assert( a.type() == typeid(Type) );
assert( std::any_cast<Type>(a) == 42 );
int (*xx)() = +[]() { return 42; };
using Type = decltype(xx);
std::function<long()> f = xx;
assert( f.target_type() == typeid(Type) );
assert( *f.target<Type>() == xx );
void (*xx)(int *) = +[](int *x) { delete x; };
using Type = decltype(xx);
std::shared_ptr<int> p(new int, xx);
/* assert( ??? == typeid(Type) ); */
assert( *std::get_deleter<Type>(p) == xx );
The crazy different spellings of these type-unerasure accessors I take as par for the course. What really surprises me, though, is that there doesn't seem to be any "get the typeid
" accessor for shared_ptr
! Am I just missing something on cppreference? Or is there a technical reason this particular function would be difficult to provide? Or is it just a random hole in the specification of shared_ptr
, i.e., historical reasons?
(Again, I can't think of any use-case for this, and IMHO it would be preferable if neither function
nor shared_ptr
allowed type-unerasure at all; but since they do, I'm wondering why it's so dang inconsistent.)