std::forward<T>(u) has two parameters: T and u. When T is an lvalue reference type, u will be converted to an lvalue of type T, otherwise u will be converted to an rvalue of type T. This definition of std::forward is to solve the problem of perfect forwarding of parameters in function templates that use rvalue reference parameters.
std::move is an unconditional conversion to an rvalue reference, while std::forward is a conditional conversion to an rvalue reference, which is more accurately called Perfect forwarding, and the conditions contained in std::forward It is Reference Collapsing.
std::move does not move anything. std::forward does not forward anything. At runtime, they do nothing. No executable code is generated, and no one-bit code is generated.
std::move and std::forward are just functions that perform conversion (to be exact, they should be function templates). std::move unconditionally converts its parameters into an rvalue, and std::forward will perform its conversion only when a specific condition is met .
std::move behaves as an unconditional rvalue conversion , by itself, it does not move anything. std::forward converts the parameter to an rvalue only when the parameter is bound by an rvalue. std::move and std::forward do nothing at runtime.
The conversion rules of forward are:
When the template parameter is a reference type T, T&&, an rvalue reference is returned
When the template parameter is a reference type T&, an lvalue reference is returned.
example:
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T>
void print(T& t){
cout << "lvalue" << endl;
}
template<typename T>
void print(T&& t){
cout << "rvalue" << endl;
}
template<typename T>
void TestForward(T && v){
print(v);
print(std::forward<T>(v));
print(std::move(v));
print(v);
}
int main()
{
cout <<"---------0--------"<< endl;
TestForward(1);
cout <<"---------1--------"<< endl;
int c = 1;
TestForward(c);
cout <<"---------2--------"<< endl;
int a = 1;
int &&x = std::move(a);
TestForward(std::forward<int &&>(x));
cout <<"---------3--------"<< endl;
int a1 = 1;
int &b = a1;
TestForward(b);
cout <<"---------4--------"<< endl;
int a2 =1 ;
TestForward(std::move(a2));
cout <<"---------5--------"<< endl;
int a3 = 1;
int &&y = std::move(a3);
TestForward(y);
}
Print result:
---------0--------
lvalue
rvalue
rvalue
lvalue
---------1--------
lvalue
lvalue
rvalue
lvalue
---------2--------
lvalue
rvalue
rvalue
lvalue
---------3--------
lvalue
lvalue
rvalue
lvalue
---------4--------
lvalue
rvalue
rvalue
lvalue
---------5--------
lvalue
lvalue
rvalue
lvalue
Article references:
C++11 new feature forward, perfect forwarding and explanation