I'm implementing a polymorphic type (call it A
) that I want to have managed exclusively via std::shared_ptr
. To allow using shared_from_this
in the constructor of derived classes, A
is allocated using new
and then initializes a member std::shared_ptr
to itself to manage its lifetime automatically. To help enforce this, I've decided to make the class-specific operator new
private, and plan to use a create()
helper function instead of new
and make_shared
. The design might look a bit funny but it makes sense in context for the UI library I'm working on. A minimal reproducible example is as follows:
struct A {
A() : m_sharedthis(this) {
}
void destroy(){
m_sharedthis = nullptr;
}
std::shared_ptr<A> self() const {
return m_sharedthis;
}
private:
friend std::shared_ptr<A> create();
std::shared_ptr<A> m_sharedthis;
};
std::shared_ptr<A> create(){
auto a = new A();
return a->self();
}
This compiles and works fine. The problem arises when I add the following code to the body of A
:
struct A {
...
private:
void* operator new(size_t size){
return ::operator new(size);
}
void operator delete(void* ptr){
::operator delete(ptr);
}
...
};
Now this fails to compile on MSVC 2017 with a rather cryptic error message:
error C2664: 'std::shared_ptr<A>::shared_ptr(std::shared_ptr<A> &&) noexcept': cannot convert argument 1 from 'A *' to 'std::nullptr_t'
note: nullptr can only be converted to pointer or handle types
What's going on here? Why is the std::shared_ptr
constructor trying to accept only nullptr
suddenly?
EDIT: Yes, in the actual code, the class does derive from std::enable_shared_from_this
, but it was not necessary to reproduce the error.