Skip to content

F.16 ("in" parameters): Move Matrix example to F.20 (return values) #1922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 13, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions CppCoreGuidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -2927,31 +2927,11 @@ For advanced uses (only), where you really need to optimize for rvalues passed t

void sink(unique_ptr<widget>); // input only, and moves ownership of the widget

Avoid "esoteric techniques" such as:

* Passing arguments as `T&&` "for efficiency".
Most rumors about performance advantages from passing by `&&` are false or brittle (but see [F.18](#Rf-consume) and [F.19](#Rf-forward)).
* Returning `const T&` from assignments and similar operations (see [F.47](#Rf-assignment-op).)

##### Example

Assuming that `Matrix` has move operations (possibly by keeping its elements in a `std::vector`):

Matrix operator+(const Matrix& a, const Matrix& b)
{
Matrix res;
// ... fill res with the sum ...
return res;
}

Matrix x = m1 + m2; // move constructor

y = m3 + m3; // move assignment
Avoid "esoteric techniques" such as passing arguments as `T&&` "for efficiency".
Most rumors about performance advantages from passing by `&&` are false or brittle (but see [F.18](#Rf-consume) and [F.19](#Rf-forward)).

##### Notes

The return value optimization doesn't handle the assignment case, but the move assignment does.

A reference can be assumed to refer to a valid object (language rule).
There is no (legitimate) "null reference."
If you need the notion of an optional value, use a pointer, `std::optional`, or a special value used to denote "no value."
Expand Down Expand Up @@ -3104,6 +3084,26 @@ The argument against is that it prevents (very frequent) use of move semantics.
* If a type is expensive to move (e.g., `array<BigPOD>`), consider allocating it on the free store and return a handle (e.g., `unique_ptr`), or passing it in a reference to non-`const` target object to fill (to be used as an out-parameter).
* To reuse an object that carries capacity (e.g., `std::string`, `std::vector`) across multiple calls to the function in an inner loop: [treat it as an in/out parameter and pass by reference](#Rf-out-multi).

##### Example

Assuming that `Matrix` has move operations (possibly by keeping its elements in a `std::vector`):

Matrix operator+(const Matrix& a, const Matrix& b)
{
Matrix res;
// ... fill res with the sum ...
return res;
}

Matrix x = m1 + m2; // move constructor

y = m3 + m3; // move assignment


##### Note

The return value optimization doesn't handle the assignment case, but the move assignment does.

##### Example

struct Package { // exceptional case: expensive-to-move object
Expand Down