If I std::dynamic_pointer_cast and the result of the underlying dynamic_cast is null, is the returned shared_ptr guaranteed to store null inside?

Viewed 597

Why I am a bit confused about this:

std::shared_ptr can be empty and std::shared_ptr can point to null and these two concepts are not equivalent.

an empty shared_ptr can store a non-null value and a shared_ptr that stores null can have a positive ref-count.

What I wonder now is how do I properly test after a std::dynamic_pointer_cast whether the cast was successful or not? the docs https://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast state:

3-4) dynamic_cast<Y*>(r.get()) (If the result of the dynamic_cast is a null pointer value, the returned shared_ptr will be empty.)

but since an empty shared_ptr isn't guaranteed to store a null value, I'm not sure what's the proper well-defined test for whether the dynamic cast succeeded

1 Answers

I'm really not super sure, but here goes:

The c++17 and c++20 standard drafts declare in (23.11.2.2.9 shared_ptr casts)

shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;

Returns:

(5.1) — When dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()) returns a nonzero value p, shared_ptr<T>(r, p)

Otherwise, shared_ptr<T>().

The default constructor of shared_ptr<T>, defined in (20.11.3.11 Constructors) has as post condition

use_count() == 0 && get() == nullptr

I read that as: if the raw pointer cast returns nullptr, the smart pointer cast will hold a nullptr.

Therefore I think that a dynamic_pointer_cast is successful, if the resulting shared pointer does not hold a null pointer (it might also hold a null pointer when successful but that is --up to now-- of no relevance in my applications).

But I must say that this was my first venture into the c++ standard and I, too, don't understand, how a failed dynamic cast could ever hold a non-null empty pointer, although I have also read that.

Related