C++11 std::forward和std::move

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

The use of std::forward in C++11

Guess you like

Origin blog.csdn.net/hyl999/article/details/108092569
Recommended