私はそれを理解するには、コードを実行する愚かなものだ...しかし、理解のために、以下の点を考慮してください。のstd ::クラスのメソッドやフィールドに*この以降のアクセスの動き
#include <iostream>
#include <memory>
#include <utility>
struct S;
void f(S && s);
struct S {
S() : i{std::vector<int>(10, 42)} {}
std::vector<int> i;
void call_f() { f(std::move(*this)); }
void read() { std::cout << " from S: " << i.at(3) << std::endl; }
};
void f(S && s) { std::cout << " from f: " << s.i.at(3) << std::endl; }
int main() {
S s;
s.call_f();
s.read();
}
これはg ++とclang ++の両方でコンパイルして実行しますが、std::vector<int>
を移動することが期待されます。これをgdbで実行してメモリを調べると、std::move
の後にアドレスがゼロに設定されていないことがわかりましたが、私はPOD以外のタイプの場合には期待していました。 したがって、私はこのコードからセグメンテーションを期待しました。
誰でもこの現象を説明できますか?なぜs
も内部フィールドも無効になっていませんか? this
の機能ですか?
セグメンテーションを「期待」しないでください!たとえあなたが(そうしなかった)コードを書いたとしても、それを期待するのは愚かです。 –
std :: move(* this)は何も移動しませんが、fの移動オーバーロードを呼び出すことはコンパイラに指示します。 fの移動オーバーロードの実装がsを混乱させないならば、あなたのインスタンスはまだ良好です。 segfaultが必要な場合は、fの内部でs.iを効果的に動かすものを追加する必要があります。 – rectummelancolique
@ correctummelancolique:こんにちは。これはコメントセクションです。 ↓↓↓↓↓の答えを掲示板/フォーラムの先祖から離れたSEのQ&Aを設定するピアレビュー機能の対象になるように、そこに答えを入れてください。ありがとう! –