isocpp / CppCoreGuidelines

The C++ Core Guidelines are a set of tried-and-true guidelines, rules, and best practices about coding in C++
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
Other
42.8k stars 5.44k forks source link

Why Resource-Management is no discussion about shared_ptr<widget>&& and unique_ptr<widget>&& ? #1916

Open ltimaginea opened 2 years ago

ltimaginea commented 2 years ago

Should add the discussion about shared_ptr<widget>&& and unique_ptr<widget>&& in Smart pointer rule summary .

Link: Smart pointer rule summary

For R.34's example code, when enter the function, the shared_ptr is copy-constructed, and this requires incrementing the strong reference count. This can incur performance costs. But if the parameter type is shared_ptr<widget>&& , this directly addresses the cost. The rvalue reference type shared_ptr<widget>&& is more efficient than the value type shared_ptr<widget> . So, I don't understand R.34 Enforcement's final line:

  • (Simple) ((Foundation)) Warn if a function takes a Shared_pointer<T> by rvalue reference. Suggesting taking it by value instead.

I modified the example code for R.34 , I think the example code should be written like this:

class WidgetUser
{
public:
    // the parameter type is shared_ptr<widget>&&
    explicit WidgetUser(std::shared_ptr<widget>&& w) noexcept:
        m_widget{std::move(w)} {}
    // ...
private:
    std::shared_ptr<widget> m_widget;
};

On the other hand, R.32 and R.33 talk about unique_ptr<widget> and unique_ptr<widget>& . But I think, unique_ptr<widget>&& is also very useful. If we take a unique_ptr<widget> parameter, its total cost would be two moves. But if we take a unique_ptr<widget>&& parameter, the total cost is one move.

The screenshots from the Scott Meyers's Effective Modern C++ Item41 is as follows: *Effective Modern C++* Item41

So, I think we should add the discussion about shared_ptr<widget>&& and unique_ptr<widget>&& in Smart pointer rule summary .

bgloyer commented 2 years ago

This was mentioned in Issue #1781 for shared_ptr

hsutter commented 2 years ago

Editors call: F.18 covers that for "sink" functions (for smart pointers, ownership transfer) to pass by &&. In our desire to keep the smart pointer passing rules simple and avoid teaching &&, we covered only unique_ptr "sink" functions where pass by value happens to have the same effect because unique_ptr happens to be move-only, but we did not cover other smart pointer "sink" functions. Those should pass by &&. We might add a guideline saying so, or perhaps add a note saying so.