Based on the source code below, here is the forwarding result:
Input parameter Forwarded to
int intNonConst: (int&)
const int intConst: (const int&)
6(just a literal): (int&&) or if (int&&) doesn’t exist, to (const int& i)
std::move(intNonConst)): (int&&)
int IntTemp(): (int&&)
Why std::forward: otherwise, when a rvalue is passed, e.g. 6, std::move or IntTemp(), it gets forwarded to &, instead of &&.
Why std::move: so that a lvalue such as intNonConst can be treated as rvalue, and therefore be forwarded to &&
Summary: std::forward is to deal with rvalue forwarding, and it does not affect rvalue reference, regardless of constness
int IntTemp() { return 0; }
void TestForwardingFuncCalled(const int& i)
{
cout << "const &" << endl;
};
void TestForwardingFuncCalled(int& i)
{
cout << "&" << endl;
};
void TestForwardingFuncCalled(int&& i)
{
cout << "&& " << endl;
};
template void TestForwardingTemplateFunc(T&& t)
{
cout << "Results with std::forward" << endl;
TestForwardingFuncCalled(std::forward(t));
cout << "Results without std::forward" << endl;
TestForwardingFuncCalled(t);
}
void TestForwarding()
{
int intNonConst = 2;
const int intConst = 3;
TestForwardingTemplateFunc(intNonConst); //with std::forward: (int&)", without std::forward: same
TestForwardingTemplateFunc(intConst); //with std::forward: (const int&)", without std::forward: same
TestForwardingTemplateFunc(6); //with std::forward: (int&&) or if (int&&) doesn't exist, to (const int& i), without std::forward: (int&)
TestForwardingTemplateFunc(std::move(intNonConst)); //with std::forward: (int&&), without std::forward: (int&)
TestForwardingTemplateFunc(IntTemp()); //with std::forward: (int&&), without std::forward: (int&)
}
void main()
{
TestForwarding();
}