From 0edfca63069a020463d5139a992f7c5146ce7629 Mon Sep 17 00:00:00 2001 From: Russell McClellan Date: Sun, 28 Apr 2019 16:56:59 -0400 Subject: [PATCH 1/2] Explain freedoms available in F.16-F.18 As I discussed in #1407, I found the existing wording confusing as I expected that the guidelines would provide me with one recommended way to author function arguments in all situations. However, the discussion on the issue clarified that the intent was to allow many ways to author functions, and only to disallow specific clearly non-optimal cases. This is my attempt to reduce that confusion, by explicitly calling out when such freedoms exist. --- CppCoreGuidelines.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 06cce5b2c..e9c987e56 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -2825,6 +2825,8 @@ Advanced parameter passing: ![Advanced parameter passing table](./param-passing-advanced.png "Advanced parameter passing") Use the advanced techniques only after demonstrating need, and document that need in a comment. +Note that the guidelines do not provide a complete decision procedure on how to write a function. +In many situations, there will be multiple ways to write a function that is in accordance with the guidelines. ### F.16: For "in" parameters, pass cheaply-copied types by value and others by reference to `const` @@ -2847,9 +2849,9 @@ When copying is cheap, nothing beats the simplicity and safety of copying, and f For advanced uses (only), where you really need to optimize for rvalues passed to "input-only" parameters: -* If the function is going to unconditionally move from the argument, take it by `&&`. See [F.18](#Rf-consume). +* If the function is going to unconditionally move from the argument, take it by `&&`. See [F.18](#Rf-consume). You may also provide a `const &` overload that copies the argument rather than moves it, although this is not required. * If the function is going to keep a copy of the argument, in addition to passing by `const&` (for lvalues), - add an overload that passes the parameter by `&&` (for rvalues) and in the body `std::move`s it to its destination. Essentially this overloads a "will-move-from"; see [F.18](#Rf-consume). + add an overload that passes the parameter by `&&` (for rvalues) and in the body `std::move`s it to its destination. Essentially this overloads a "will-move-from"; see [F.18](#Rf-consume). It also could be appropriate to remove the `const&` overload and only keep the `&&` overload. * In special cases, such as multiple "input + copy" parameters, consider using perfect forwarding. See [F.19](#Rf-forward). ##### Example @@ -2950,6 +2952,10 @@ Note that the `std::move(v)` makes it possible for `store_somewhere()` to leave [That could be dangerous](#Rc-move-semantic). +##### Note + +You may also provide an overload that takes the argument by `const X&` and copies the value rather than move it. However, this is not required, and in some cases may not be possible. + ##### Exception Unique owner types that are move-only and cheap-to-move, such as `unique_ptr`, can also be passed by value which is simpler to write and achieves the same effect. Passing by value does generate one extra (cheap) move operation, but prefer simplicity and clarity first. From 7802043be7907a6e31d70c0d3f736f81b28bfafb Mon Sep 17 00:00:00 2001 From: Russell McClellan Date: Thu, 2 May 2019 19:51:34 -0400 Subject: [PATCH 2/2] Remove note in F.18 --- CppCoreGuidelines.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index e9c987e56..daf6f5b1c 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -2952,10 +2952,6 @@ Note that the `std::move(v)` makes it possible for `store_somewhere()` to leave [That could be dangerous](#Rc-move-semantic). -##### Note - -You may also provide an overload that takes the argument by `const X&` and copies the value rather than move it. However, this is not required, and in some cases may not be possible. - ##### Exception Unique owner types that are move-only and cheap-to-move, such as `unique_ptr`, can also be passed by value which is simpler to write and achieves the same effect. Passing by value does generate one extra (cheap) move operation, but prefer simplicity and clarity first.