私はCppCon 2015のビデオを見ています。C++ラムダ:良いリファレンスと悪いリファレンス
アーサーは説明したが、私はそれを得ることはありません...アーサーは悪い参照は、終了し、ローカル変数を参照しているが、スタックを出た後にクリーンアップするものとローカル変数がなくなっていると言いますだから問題は何ですか?
私はCppCon 2015のビデオを見ています。C++ラムダ:良いリファレンスと悪いリファレンス
アーサーは説明したが、私はそれを得ることはありません...アーサーは悪い参照は、終了し、ローカル変数を参照しているが、スタックを出た後にクリーンアップするものとローカル変数がなくなっていると言いますだから問題は何ですか?
@ Barryの回答が別の言い方で言ったことを説明したいと思います。
BAD_increment_by
の中に起こったことを書き留めましょう。
y
があります。y
参照。これによりy
という参照が作成されます。さて、彼らは同じ名前を持っている、それは混乱している...最初の1つを "値y
"と呼び、2番目のものを "y
"と呼びましょう。y
が使用されています。BAD_increment_by
によって返されます。 BAD_increment_by
から戻った後、
y
は存在しません。y
はまだy
...y
が存在しません!参照y
は何かが存在しないことを指しています!誰かがラムダを呼び出す、
y
読み込まれます。y
は参照番号であるため、値y
にリダイレクトされます。y
ですか、それとも私の幻覚ですか?結論は次のとおりです。ラムダが呼び出されると、ダングリングリファレンスが使用されます。この動作は未定義です。
ありがとうございました!今私はそれを得た。 – athos
BAD_increment_by
は、その中にy
の参照を含むクロージャを返しますが、y
は、その関数が返ったときに範囲外になるため、参照が含まれていません。そのクロージャを呼び出す試みは未定義の動作です。
それは同じ理由で悪い:
int& BAD_copy(int x) { return x; }
が悪いです。
ラムダは、operator()
のクラスの省略形と考えることができるので、関数のように扱うことができます。
auto BAD_increment_by(int y)
{
return [&](int x){return x+y;};
}
は次のために短い手考慮することができる:
struct BadClosure
{
int& y;
BadClosure(int& y) // y is the only variable in scope
: y(y) // So the `&` only captures 'y'
{}
auto operator()(int x){return x+y;}
};
auto BAD_increment_by(int y)
{
return BadClosure(y);
}
だから私は上記を使用する場合:あなたは `INT&F(と間違って何
int main()
{
// This object now has a reference to
// parameter 'y' from the function `BAD_increment_by()`
//
// But this function has exited.
// So the reference held by this object is no longer
// valid (ie it is a dangling reference).
auto addTwo = BAD_increment_by(2);
// Now use it
// Internally this access the member y
// which is a reference to the parameter 'y'
// from a function that is no longer executing.
std::cout << addTwo(5) << "\n";
}
知っていますか){int型のx = 5; return x;} '? – immibis
問題はまさにあなたが言ったことです - あなたは何かを参照しているものを返しています。そんなことで何ができますか? –