次のコードを直接持っています: http://www.justsoftwaresolutions.co.uk/cplusplus/rvalue_references_and_perfect_forwarding.html
g++ 4.8.1 で次のようにコンパイル: g++ -std=c++11 testforward.cpp -o testforward.exe
#include <cstdlib>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
class X
{
std::vector<double> data;
public:
X():
data(100000) // lots of data
{}
X(X const& other): // copy constructor
data(other.data) // duplicate all that data
{}
X(X&& other): // move constructor
data(std::move(other.data)) // move the data: no copies
{}
X& operator=(X const& other) // copy-assignment
{
data=other.data; // copy all the data
return *this;
}
X& operator=(X && other) // move-assignment
{
data=std::move(other.data); // move the data: no copies
return *this;
}
};
void g(X&& t)
{
std::cout << "t in g is rvalue" << std::endl ;
}
void g(X& t)
{
std::cout << "t in g is lvalue" << std::endl ;
}
template<typename T>
void f(T&&t)
{
g(std::forward<T>(t)) ;
}
void h(X &&t)
{
g(t) ;
}
int main()
{
X x;
f(x); // 1
f(X()); // 2
//h(x); //compile error
h(X()); // 3
}
著者によると、以下に説明します。
右辺値参照を関数テンプレートと組み合わせると、興味深い相互作用が得られます。関数パラメーターの型がテンプレート型パラメーターへの右辺値参照である場合、左辺値が渡された場合、型パラメーターは左辺値参照であると推定されます。それ以外の場合は入力...
このテストの結果出力は次のとおりです。
t in g is lvalue
t in g is rvalue
t in g is lvalue
f(x) get "t in g is lvalue" は期待どおりです !!
f(X()) get "t in g is rvalue" 、はい、それが std::forward に使用されたものです
h(X()) get "t in g is lvalue" 、これは私の質問です。関数 h はテンプレート関数ではないことがわかります。著者が説明しているように、「右辺値参照を関数テンプレートと組み合わせると、興味深い結果が得られます。相互作用」はそうではありませんが、それでもこの関数出力「t in g is lvalue」は、この興味深い相互作用がテンプレート関数だけでなく、通常の関数にも発生することを意味します!!
コードを次のように変更すると:
void h(X &&t)
{
g(std::forward<X>(t)) ;
}
「t in g is rvalue」が得られます!!!
テストによると、作者は「右辺値参照を関数テンプレートと組み合わせると、興味深い相互作用が得られる」と説明していると言いましたが、実際にはテンプレート関数だけでなく、通常の関数にも適用されます。または、私の英語が苦手なので、できますこの説明を聞き取れませんよね?!
編集 :
void h(X &&t)
{
g(t) ;
}
void h(X &t)
{
g(t) ;
}
h(x); //get "t in g is lvalue"
h(X()); //get "t in g is lvalue"
=====================================================
void h(X &&t)
{
g(std::forward<X>(t)) ;
}
void h(X &t)
{
g(std::forward<X>(t)) ;
}
h(x); //get "t in g is rvalue"
h(X()); //get "t in g is rvalue"
テンプレート関数のみのように見えますが、std::forward の cprrect 使用法を取得します !!!