I have a factory function in factory.h which returns an std::shared_ptr
to a base class in foo.h. factory.h uses
This:
std::shared_ptr ptr(nullptr);
should not warn. It is a perfectly valid statement, and has no need to know the complete type of foo
. It is likely that it is warning for you because nullptr
is being emulated. Neither should this warn:
std::shared_ptr ptr;
and the two are specified to be equivalent:
constexpr shared_ptr(nullptr_t) : shared_ptr() { }
In this scene, why doesn't std::shared_ptr need to know the complete type of class foo?
The definitions of create_foo_A
and create_foo_B
will need to know the complete type of foo
. But the declarations do not.
In a nutshell, the shared_ptr
constructor needs to know the complete definition of U
. But little else does. There is a more complete survey in this answer:
https://stackoverflow.com/a/6089065/576911
So if you said instead:
std::shared_ptr ptr((foo*)0);
Then you have undefined behavior. Apparently VC++ will warn. libc++ gives a hard error. Whereas using nullptr
is quite ok, at least according to C++11.
In summary, none of your examples require the complete definition of foo
.
[util.smartptr.shared.dest]
~shared_ptr();
Effects:
*this
is empty or shares ownership with another shared_ptr
instance (use_count() > 1
), there are no side effects.[util.smartptr.shared.const]
constexpr shared_ptr() noexcept;
Effects: Constructs an empty shared_ptr
object.
[util.smartptr.shared]
In the synopsis:
constexpr shared_ptr(nullptr_t) : shared_ptr() { }