dimanche 15 mars 2020

Is it safe to call a method on a smart pointer that is moved-from in the arguments?

Is this code safe? Does the answer change if the method accepts by value or by rvalue ref? Does it change for unique_ptr?

struct foo
{
    void bar(std::shared_ptr<foo> p) // or std::shared_ptr<foo>&&
    {
        // the object will be deleted at the end of the call unless p is
        // moved/copied elsewhere at some point
    }
};

int main()
{
    auto p = std::make_shared<foo>();
    p->bar(std::move(p));
    return 0;
}

The main question is specifically on this line:

p->bar(std::move(p));

Is this guaranteed to always capture the current value of p.operator->() before constructing the argument? Or could this happen after moving-from p?

(Note: I am confident that this is safe for std::shared_ptr<foo>&& argument, as then the actual move-construction doesn't happen until inside the method body, if at all. But when passed by value, can the argument construction [which includes the move-construction] occur prior to calling p.operator->() or is it always strictly afterwards?)

Aucun commentaire:

Enregistrer un commentaire