When using std::shared_ptr
it can often be useful to make use of std::enable_shared_from_this<T>
so that you have access to the shared_from_this()
function.
One requirement of using shared_from_this()
is that all instances of the object are constructed using std::shared_ptr
. While this is a perfectly fine requirement, it feels very difficult to enforce to future users of the class.
If I create an object:
class MyClass : public std::enable_shared_from_this<MyClass>
{
public:
MyClass()
{
}
void doAThing()
{
// something I need done asynchronously
}
void someFunction()
{
std::weak_ptr<MyClass> w (shared_from_this());
// we need to use a lambda that is executed asynchronously and
// so we pass the std::weak_ptr to it to check this object still exists it is executed
std::function<void()> f = [w]()
{
if (! w.expired())
w.lock()->doAThing();
};
callAsynchronously (f); // this function passes the lambda to some queue and executes it asynchronously
}
};
and then someone - perhaps years later - uses this class without constructing it as a shared_ptr...
MyClass m;
m.someFunction();
then we get a runtime crash:
libc++abi.dylib: terminating with uncaught exception of type std::__1::bad_weak_ptr: bad_weak_ptr
To be clear, I understand the solution to this is:
std::shared_ptr<MyClass> m = std::make_shared<MyClass>();
m->someFunction();
(of course one would need to ensure that the shared_ptr
existed long enough for the asynchronous callback to execute, but I'm ignoring that here).
My question is this - how can we add some kind of static assertion in the constructor of an object that inherits from std::enable_shared_from_this<T>
so that any construction of that object not as a std::shared_ptr
is picked up at compile time rather than run time?
The following code with a
create
-function worked for me without exception.