vendredi 1 juillet 2016

Accept move-only parameter by value or rvalue reference

The accepted answer of this post Pass by value vs pass by rvalue reference says that:

For move-only types (as std::unique_ptr), pass-by-value seems to be the norm...

I'm a little bit doubtful about that. Let's say there is some non-copyable type, Foo, which is also not cheap to move; and some type Bar that has a member Foo.

class Foo {
public:
    Foo(const Foo&) = delete;
    Foo(Foo&&) { /* quite some work */ }
    ...
};

class Bar {
public:
    Bar(Foo f) : f_(std::move(f)) {}    // (1)
    Bar(Foo&& f) : f_(std::move(f)) {}  // (2)
    // Assuming only one of (1) and (2) exists at a time

private:
    Foo f_;
};

Then for the following code:

Foo f;
...
Bar bar(std::move(f));

Constructor (1) incurs 2 move constructions, while constructor (2) only incurs 1. I also remember reading in Scott Meyers's Effective Modern C++ about this but can't remember which item immediately.

So my question is, for move-only types (or more generally, when we want to transfer the ownership of the argument), shouldn't we prefer pass-by-rvalue-reference for better performance?

Aucun commentaire:

Enregistrer un commentaire