Reputation: 5856
The distinction between std::move
and std::forward
is well known, we use the latter to preserve the value category of a forwarded object and the former to cast to rvalue reference in order to enable move semantics.
In effective modern C++, a guideline exists that states
use
std::move
on rvalue references,std::forward
on universal references.
Yet in the following scenario (and scenarios where we don't want to change value category),
template <class T>
void f(vector<T>&& a)
{
some_func(std::move(a));
}
where a
is not a forwarding reference but a simple rvalue reference, wouldn't it be exactly the same to do the following?
template <class T>
void f(vector<T>&& a)
{
some_func(std::forward<decltype(a)>(a));
}
Since this can be easily encapsulated in a macro like this,
#define FWD(arg) std::forward<decltype(arg)>(arg)
isn't it convenient to always use this macro definition like so?
void f(vector<T>&& a)
{
some_func(FWD(a));
}
Aren't the two ways of writing this exactly equivalent?
Upvotes: 7
Views: 1226
Reputation: 8141
Eh. Debatable. In your particular example it is equivalent. But I wouldn't make it a habit. One reason is because you want a semantic distinction between forwarding and moving. Another reason is because to have a consistent API you'd have to have MOV
in addition to FWD
, and that really looks bad and doesn't do anything. More importantly, though, is that your code can fail unexpectedly.
Consider the following code:
#include <iostream>
using namespace std;
#define FWD(arg) std::forward<decltype(arg)>(arg)
struct S {
S() { cout << "S()\n"; }
S(const S&) { cout << "S(const S&)\n"; }
S(S&&) { cout << "S(S&&)\n"; }
};
void some_func(S) {}
void f(S&& s)
{
some_func(FWD(s));
}
int main()
{
f(S{});
}
This prints out
S()
S(S&&)
However, if I just change the FWD
line to have another (seemingly optional) pair of parentheses, like this:
void f(S&& s)
{
some_func(FWD((s)));
}
Now we get
S()
S(const S&)
And this is because now we're using decltype
on an expression, which evaluates to an lvalue reference.
Upvotes: 8