mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
Merged F.20 into F.15 (issue #1)
This commit is contained in:
parent
1f540b5021
commit
65dc9e9c37
|
@ -1785,7 +1785,6 @@ Argument passing rules:
|
||||||
* [F.17: Use a `not_null<T>` to indicate "null" is not a valid value](#Rf-nullptr)
|
* [F.17: Use a `not_null<T>` to indicate "null" is not a valid value](#Rf-nullptr)
|
||||||
* [F.18: Use a `span<T>` or a `span_p<T>` to designate a half-open sequence](#Rf-range)
|
* [F.18: Use a `span<T>` or a `span_p<T>` to designate a half-open sequence](#Rf-range)
|
||||||
* [F.19: Use a `zstring` or a `not_null<zstring>` to designate a C-style string](#Rf-string)
|
* [F.19: Use a `zstring` or a `not_null<zstring>` to designate a C-style string](#Rf-string)
|
||||||
* [F.20: Use a `const T&` parameter for a large object](#Rf-const-T-ref)
|
|
||||||
* [F.21: Use a `T` parameter for a small object](#Rf-T)
|
* [F.21: Use a `T` parameter for a small object](#Rf-T)
|
||||||
* [F.22: Use `T&` for an in-out-parameter](#Rf-T-ref)
|
* [F.22: Use `T&` for an in-out-parameter](#Rf-T-ref)
|
||||||
* [F.23: Use `T&` for an out-parameter that is expensive to move (only)](#Rf-T-return-out)
|
* [F.23: Use `T&` for an out-parameter that is expensive to move (only)](#Rf-T-return-out)
|
||||||
|
@ -2219,10 +2218,16 @@ If you have multiple values to return, [use a tuple](#Rf-T-multi) or similar mul
|
||||||
**For an "in-out" parameter:** Pass by non-`const` reference. This makes it clear to callers that the object is assumed to be modified.
|
**For an "in-out" parameter:** Pass by non-`const` reference. This makes it clear to callers that the object is assumed to be modified.
|
||||||
|
|
||||||
**For an "input-only" value:** If the object is cheap to copy, pass by value.
|
**For an "input-only" value:** If the object is cheap to copy, pass by value.
|
||||||
Otherwise, pass by `const&`. It is useful to know that a function does not mutate an argument, and both allow initialization by rvalues.
|
Otherwise, pass by `const&` which is always cheap. Both let the caller know that a function will not modify the argument, and both allow initialization by rvalues.
|
||||||
What is "cheap to copy" depends on the machine architecture, but two or three words (doubles, pointers, references) are usually best passed by value.
|
What is "cheap to copy" depends on the machine architecture, but two or three words (doubles, pointers, references) are usually best passed by value.
|
||||||
In particular, an object passed by value does not require an extra reference to access from the function.
|
In particular, an object passed by value does not require an extra reference to access from the function.
|
||||||
|
|
||||||
|
##### Example
|
||||||
|
|
||||||
|
void fct(const string& s); // OK: pass by const reference; always cheap
|
||||||
|
|
||||||
|
void fct2(string s); // bad: potentially expensive
|
||||||
|
|
||||||
![Advanced parameter passing table](./param-passing-advanced.png "Advanced parameter passing")
|
![Advanced parameter passing table](./param-passing-advanced.png "Advanced parameter passing")
|
||||||
|
|
||||||
For advanced uses (only), where you really need to optimize for rvalues passed to "input-only" parameters:
|
For advanced uses (only), where you really need to optimize for rvalues passed to "input-only" parameters:
|
||||||
|
@ -2259,10 +2264,20 @@ Assuming that `Matrix` has move operations (possibly by keeping its elements in
|
||||||
|
|
||||||
y = m3 + m3; // move assignment
|
y = m3 + m3; // move assignment
|
||||||
|
|
||||||
##### Note
|
##### Notes
|
||||||
|
|
||||||
The return value optimization doesn't handle the assignment case.
|
The return value optimization doesn't handle the assignment case.
|
||||||
|
|
||||||
|
A reference may 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."
|
||||||
|
|
||||||
|
##### Enforcement
|
||||||
|
|
||||||
|
* (Simple) ((Foundation)) Warn when a parameter being passed by value has a size greater than `4 * sizeof(int)`.
|
||||||
|
Suggest using a `const` reference instead.
|
||||||
|
|
||||||
|
|
||||||
**See also**: [implicit arguments](#Ri-explicit).
|
**See also**: [implicit arguments](#Ri-explicit).
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
@ -2398,30 +2413,6 @@ When I call `length(s)` should I test for `s == nullptr` first? Should the imple
|
||||||
|
|
||||||
**See also**: [Support library](#S-gsl).
|
**See also**: [Support library](#S-gsl).
|
||||||
|
|
||||||
### <a name="Rf-const-T-ref"></a> F.20: Use a `const T&` parameter for a large object
|
|
||||||
|
|
||||||
##### Reason
|
|
||||||
|
|
||||||
Copying large objects can be expensive. A `const T&` is always cheap and protects the caller from unintended modification.
|
|
||||||
|
|
||||||
##### Example
|
|
||||||
|
|
||||||
void fct(const string& s); // OK: pass by const reference; always cheap
|
|
||||||
|
|
||||||
void fct2(string s); // bad: potentially expensive
|
|
||||||
|
|
||||||
**Exception**: Sinks (that is, a function that eventually destroys an object or passes it along to another sink), may benefit ???
|
|
||||||
|
|
||||||
##### Note
|
|
||||||
|
|
||||||
A reference may 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."
|
|
||||||
|
|
||||||
##### Enforcement
|
|
||||||
|
|
||||||
* (Simple) ((Foundation)) Warn when a parameter being passed by value has a size greater than `4 * sizeof(int)`.
|
|
||||||
Suggest using a `const` reference instead.
|
|
||||||
|
|
||||||
### <a name="Rf-T"></a> F.21: Use a `T` parameter for a small object
|
### <a name="Rf-T"></a> F.21: Use a `T` parameter for a small object
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user