重複の可能性:
フォワードを使用する利点
私はそれが何をするのか、そしていつそれを使うのかを知っていますが、それでもそれがどのように機能するのか頭を包むことができません。std::forward
テンプレート引数の推論の使用が許可された場合、可能な限り詳細に説明し、いつ正しくないかを説明してください。
私の混乱の一部は、このです:「それは名前を持っている場合、それは左辺値だ」 -それがない理由の場合だならばstd::forward
、私は合格したときに異なる動作をthing&& x
対thing& x
?
まず、std::forward
標準に従って何が行われるかを見てみましょう。
§20.2.3 [forward] p2
戻り値:
static_cast<T&&>(t)
(ここT
で、は明示的に指定されたテンプレートパラメーターでt
あり、は渡された引数です。)
ここで、参照の折りたたみルールを思い出してください。
TR R
T& & -> T& // lvalue reference to cv TR -> lvalue reference to T
T& && -> T& // rvalue reference to cv TR -> TR (lvalue reference to T)
T&& & -> T& // lvalue reference to cv TR -> lvalue reference to T
T&& && -> T&& // rvalue reference to cv TR -> TR (rvalue reference to T)
次に、完全な転送を採用したいクラスを見てみましょう。
template<class T>
struct some_struct{
T _v;
template<class U>
some_struct(U&& v)
: _v(static_cast<U&&>(v)) {} // perfect forwarding here
// std::forward is just syntactic sugar for this
};
そして今、呼び出しの例:
int main(){
some_struct<int> s1(5);
// in ctor: '5' is rvalue (int&&), so 'U' is deduced as 'int', giving 'int&&'
// ctor after deduction: 'some_struct(int&& v)' ('U' == 'int')
// with rvalue reference 'v' bound to rvalue '5'
// now we 'static_cast' 'v' to 'U&&', giving 'static_cast<int&&>(v)'
// this just turns 'v' back into an rvalue
// (named rvalue references, 'v' in this case, are lvalues)
// huzzah, we forwarded an rvalue to the constructor of '_v'!
// attention, real magic happens here
int i = 5;
some_struct<int> s2(i);
// in ctor: 'i' is an lvalue ('int&'), so 'U' is deduced as 'int&', giving 'int& &&'
// applying the reference collapsing rules yields 'int&' (& + && -> &)
// ctor after deduction and collapsing: 'some_struct(int& v)' ('U' == 'int&')
// with lvalue reference 'v' bound to lvalue 'i'
// now we 'static_cast' 'v' to 'U&&', giving 'static_cast<int& &&>(v)'
// after collapsing rules: 'static_cast<int&>(v)'
// this is a no-op, 'v' is already 'int&'
// huzzah, we forwarded an lvalue to the constructor of '_v'!
}
この段階的な回答が、あなたや他の人がどのようにstd::forward
機能するかを理解するのに役立つことを願っています。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加