2017-12-17 28 views
4

cppreference.comによると、moveは署名なぜstd :: moveはrvalue参照を引数として取るのですか?

template< class T > 
typename std::remove_reference<T>::type&& move(T&& t) noexcept; 

なぜそれがそのarugmentとして右辺値参照T&& tを取るんを持っていますか?私は次のコード

void foo(int&& bar) { 
    cout << "baz" << endl; 
} 

int main(){ 
    int a; 
    foo(a); 
} 

をしようとしたとき

はまた、私は何が起こっているかを「右辺値参照は左辺値にバインドすることはできません」コンパイラから

をエラーが発生しましたか?私は困惑している。

+1

あなたは 'T && t'がrvalue参照であると仮定しました。これは時期尚早です。 'T && t'が何であるかを知るまでは、' T && t'がrvlaue参照であるかどうかを言う方法がありません。 'T 'が推論されるとき、外的状況に応じて左辺値と左辺値の間で' T && t'が切り替わるように、言語規則(型減算と参照崩壊)が故意に作られる。 – AnT

+1

それは混乱しています。ダブルアンプ&&は、コンテキストに応じて2つの意味のいずれかを持ちます。テンプレートパラメータでは、 "転送参照"を表します。 –

答えて

8

これは右辺値ではありませんが、forwarding referenceです。それは議論の価値カテゴリーを保存することができる。つまり、std::moveはlvalueとrvalueの両方をとり、無条件にrvalueに変換できます。

転送参照は、関数の引数の値カテゴリを保持する特別な種類の参照で、std :: forwardを使用して転送することができます。転送の参照のいずれかである:

1)同じ 関数テンプレートのCV-非修飾型テンプレートパラメータに右辺値 参照として宣言された関数テンプレートの機能パラメータ:& &から推定される場合を除いて

2)オート中括弧で囲まれたイニシャライザリスト。

一方、int&&は正の参照番号です。テンプレートテンプレートのパラメータがTT&&のタイプ、つまり推定タイプがTの場合、パラメータは転送参照です。

+0

私は学ぶほどのことです。ありがとう –

関連する問題