-
Notifications
You must be signed in to change notification settings - Fork 16
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
Add bugprone-move-forwarding-reference check to clang-tidy #695
base: master
Are you sure you want to change the base?
Conversation
@phate the compiler really didn't like the use of std::forward, but I'm not immediately sure exactly why, from looking at the errors |
Is there a reason why |
@haved Fixed it now. I forgot to compile the first time. |
@phate I read up on the rules surrounding
and I do not think it makes sense to use |
@haved Could you elaborate or have a link for me? @caleridas Do you have an opinion here? The code was originally written by you (long time ago). |
Reading the documentation of When we use the pattern template<typename T>
T func(T&& t) {
t.push_back(t.size());
return std::forward<T>(t);
}
If an rvalue is passed into When If It is honestly a bit fun to have functions like this, because it makes it possible to do operations in-place without any copying or moving, but also to take a temporary value and construct a new result type if needed. The downside is that the function does not compile if it is given a const reference, which can be a bit surprising when the function seemingly is capable of returning a new container. Then again, a compile error is much more preferable than introducing subtle bugs. The alternative I was suggesting is template<typename Container, typename Reductor>
Container
commutative_pairwise_reduce(Container args, const Reductor & reductor) {
...
return args; // No need for std::move() or std::forward(), let named return value optimization do its thing This will always compile, and if you have a list of arguments you want to change "in place", you can call it like
which will perform one move-construction, but that's it. For reference, every call to I personally think this approach is a bit nicer, as it reduces the amount of C++ mental gymnastics one must go through. For the use cases we have, I think the total amount of move-construction should be the same, since we get named return value optimization. What do you think @phate, @caleridas? |
@haved Thanks a lot for the write-up and condensing it down for me. I agree with you. @caleridas Unless there are any objections from your side, I will change it to @haved 's suggestion. |
@caleridas Opinion? |
The explanation above by @haved s accurate, and I concur that && should not be used (unless you have a function that should be templated on "constness" of argument). |
@@ -52,7 +52,7 @@ pairwise_reduce(Container && args, const Reductor & reductor) | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would suggest removing the && and just use plain value. It is up to caller to move values into it if it wants to pass ownership instead of copying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
# Conflicts: # .clang-tidy
No description provided.