1

There is some function that has rvalue argument. There is an other function that also has rvalue argument. The first function calls the second function:

void inner(int&& a)
{/* ... */}

void outer(int&& a)
{
    inner(std::move(a));
}

I used std::move because we use std::move to pass parameter as rvalue. But my colleague said that std::forward is more appropriate here because we forward (not move) rvalue reference here:

void outer(int&& a)
{
    inner(std::forward(a));
}

Is it true? Which variant is more correct?

Akira
  • 4,385
  • 3
  • 24
  • 46
Andrey Epifantsev
  • 976
  • 1
  • 11
  • 27

2 Answers2

2

Forward is a conditional move. Using it here is like saying you should wrap statements in if (true).

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • 1
    I used to wrap a lot of my statements in `if (true)`, but someone once told me that good code is symmetric, and now I consistently use `if (true == true)`. – Kerrek SB Sep 05 '17 at 12:07
  • @kerrek as a general rule of style, `if (A==B)` is ambiguous. `A==B` is what? Do `if ((A==B)==true)` to make it clear. – Yakk - Adam Nevraumont Sep 05 '17 at 12:16
  • You're right -- to the refactorer! – Kerrek SB Sep 05 '17 at 12:20
  • @kerrek C++17 can help here. Use a fold expression; first template entire program on `bool...trues`. Then wrap all conditionals in `== ... == bools`. Now you can increase the style tier of code by 1 by simply adding `true` in one spot. No refactoring tools needed. – Yakk - Adam Nevraumont Sep 05 '17 at 12:50
2

The usage of forward is slightly different. It is used like this:

void outer(int&& a)
{
    inner(std::forward<int>(a));
}

On non template code, forward is really confusing since there is no forwarding done.

Forwarding exist because of forwarding reference and reference collapsing. Take away those and no more forwarding magic.

In your case you're receiving an rvalue reference. Moving it is the right thing to do.

Forward is conditional move that depends on the declared type of the variable you might want to move. If that variable is an lvalue reference, std::forward<T>(t) won't move it.

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141