std :: forward <T>(u)には、Tとuの2つのパラメーターがあります。Tが左辺値参照型の場合、uはタイプTの左辺値に変換されます。それ以外の場合、uはタイプTの右辺値に変換されます。std :: forwardのこの定義は、右辺値参照パラメーターを使用する関数テンプレート内のパラメーターの完全な転送の問題を解決するためのものです。
std :: moveは無条件に右辺値参照に変換され、std :: forwardは条件付きで右辺値参照に変換されます。より正確には完全転送と呼ばれ、std :: forwardに含まれる条件は参照の折りたたみです。
std :: moveは何も移動しません。std :: forwardは何も転送しません。実行時には、何もしません。実行可能コードは生成されず、1ビットコードも生成されません。
std :: moveとstd :: forwardは、変換を実行する単なる関数です(正確には、関数テンプレートである必要があります)。std :: moveは、そのパラメーターを無条件に右辺値に変換し、std :: forwardは、特定の条件が満たされた場合にのみ変換を実行します。
std :: moveは、無条件の右辺値変換として動作し、それ自体では何も移動しません。std :: forwardは、パラメーターが右辺値によってバインドされている場合にのみ、パラメーターを右辺値に変換します。std :: moveおよびstd :: forwardは、実行時に何もしません。
フォワードの変換ルールは次のとおりです。
テンプレートパラメータが参照型T、T &&の場合、右辺値参照が返されます
テンプレートパラメータが参照型T&の場合、左辺値参照が返されます。
例:
#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);
}
結果の印刷:
--------- 0 --------
lvalue
rvalue
rvalue
lvalue
--------- 1 --------
lvalue
lvalue
rvalue
lvalue
------ --- 2 --------
lvalue
rvalue
rvalue
lvalue
--------- 3 --------
lvalue
lvalue
rvalue
lvalue
--------- 4 --- ------
左辺値
右辺
値
左辺値
--------- 5 --------
左辺
値左辺値
右辺
値左辺値
記事の参照: