Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check whether an object derived from enable_shared_from_this is managed by shared_ptr?

Suppose I have a class derived from std::enable_shared_from_this

struct foo
  : std::enable_shared_from_this<foo>
{
    std::shared_ptr<foo> get_shared()
    {
        return shared_from_this();
    }

    bool is_shared() const
    {
        /* implementation ??? */
    }
};

foo  A;
auto S= A.get_shared();   // UB (pre c++17) or exception (c++17)

Prior to c++17, there appears to be no way to detect whether an object foo is actually managed by a shared_ptr. Correct?

But even for c++17, I'm not sure how to best implement such a detection. One obvious approach is

bool foo::is_shared() const
{
    try {
        shared_from_this();
    } catch(...) { 
        return false;
    }
    return true;
}

But can the try-catch be avoided? Can I use weak_from_this()? How?

like image 628
Walter Avatar asked Dec 18 '18 16:12

Walter


1 Answers

You can implement is_shared leveraging weak_from_this() in C++17 like:

bool is_shared() const
{
    return !weak_from_this().expired();
}

This is exception free and will only return true is the object is actually managed by a shared_ptr.

Pre C++17 there isn't a way to check since it is undefined behavior to call shared_from_this() when the object is not owned by a shared_ptr. It wasn't until weak_from_this() was introduced in C++17 that we could access the private weak_ptr member of std::enable_shared_from_this (via a copy) that we can inspect the state in a defined manner.

like image 131
NathanOliver Avatar answered Dec 09 '22 16:12

NathanOliver