Reputation: 6340
Does std::move need to be combined with std::forward when using universal references? For example, which of the following two pieces of code is correct?
void bar(auto && x) {
auto y(std::move(std::forward<decltype(x)>(x)));
}
or
void bar(auto && x) {
auto y(std::move(x));
}
Basically, I want to move the memory of x into y and I don't care if it's an l-value reference or an r-value reference. Certainly, I don't want const
values here.
Upvotes: 1
Views: 203
Reputation: 31
/!\ BEWARE /!\
Using std::move
for a universal reference can be a very bad idea and highly recommended to avoid :
auto name = getName(); // std::string getName();
bar(name);
// 'name' value has been moved... And its value now is unknown, empty at best.
move(forward(x))
is bad style and shouldn't be used.
You should use std::move
for rvalue references and std::forward
for universal references. Cf. formal definitions.
auto&&
is a universal reference, therefore what you should write is :
void bar(auto&& x) {
auto y(std::forward<decltype(x)>(x));
}
Upvotes: 0
Reputation: 60979
A move
will suffice if you want to move regardless of the value category of the argument. forward
is superfluous in that case as move(forward(x))
is always an rvalue, no matter what forward(x)
is.
If you only wanted to move depending on whether the argument to bar
was an rvalue, you should use forward
on its own, which propagates the value category.
Upvotes: 2