[解決済み] std::forwardはどのように機能するのですか?重複] [重複
2022-03-05 05:24:02
質問
重複の可能性があります。
フォワードを使用するメリット
何をするのか、どんなときに使うのか、わかってはいるけれど
まだ
の仕組みがよくわからないのですが。できるだけ詳しく、どのような場合に
std::forward
は、テンプレート引数控除を使用することが許可されている場合、不正確である。
私の混乱の一端はこれです。
もし名前があれば、それはlvalueです。
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
が動作します。
関連
-
[解決済み] テスト
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] std::move()とは何ですか?また、どのような場合に使用するのですか?
-
[解決済み] const std::string & をパラメータとして渡す時代は終わったのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++
-
[解決済み】'std::cout'への未定義の参照
-
[解決済み】auto&&は何を教えてくれるの?
-
[解決済み] std::moveとstd::forwardの違いは何ですか?