Why not always use std :: forward?

The difference between std::move and std::forward well known, we use the latter to maintain the category of values โ€‹โ€‹of the redirected object, and the former to refer to rvalue to include the semantics of movement.

In efficient modern C ++, there is a rule that says

use std::move for rvalue links, std::forward for universal links.

However, in the following scenario (and scenarios where we do not want to change the category of values),

 template <class T> void f(vector<T>&& a) { some_func(std::move(a)); } 

where a not a link for forwarding, but a simple link to rvalue, wouldn't the following do the same?

 template <class T> void f(vector<T>&& a) { some_func(std::forward<decltype(a)>(a)); } 

Since it 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 this?

 void f(vector<T>&& a) { some_func(FWD(a)); } 

Are there two ways to write this equivalent?

+5
source share
1 answer

E. It is debatable. In your specific example, this is equivalent. But I would not become a habit. One reason is that you want a semantic difference between forwarding and moving. Another reason is that in order to have a consistent API, you need to have MOV in addition to FWD , and it really looks bad and does nothing. More importantly, your code may end 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{}); } 

Will print

S ()
S (S & &)

However, if I just changed the FWD line to have a different (seemingly optional) pair of parentheses, for example:

 void f(S&& s) { some_func(FWD((s))); } 

Now we get

S ()
S (const S &)

And this is because now we use decltype for an expression that evaluates to an lvalue reference.

+6
source

Source: https://habr.com/ru/post/1245796/


All Articles