14

少し前に同じような質問をしましたが、詳細はまだわかりません。

  1. ポストブリットコンストラクターはどのような状況で呼び出されますか?

  2. オブジェクトを移動するセマンティクスは何ですか?ポストブリットおよび/または破壊されますか?

  3. ローカル変数を値で返すとどうなりますか?暗黙的に移動されますか?

  4. 式を右辺値にキャストするにはどうすればよいですか?たとえば、一般的なスワップはどのようになりますか?

4

2 に答える 2

16
  1. 構造体がコピーされるたびに、たとえば構造体を関数に渡すときに、postblitコンストラクターが呼び出されます。

  2. 移動はビット単位のコピーです。postblitコンストラクターが呼び出されることはありません。デストラクタが呼び出されることはありません。ビットは単純にコピーされます。オリジナルは「移動」されたため、作成または破棄する必要はありません。

  3. 移動します。これは移動の代表的な例です。

  4. swap関数を可能な限り効率的にしたい場合、関数が心配しなければならないさまざまな状況がいくつかあります。std.algorithmのスワップ関数を使用することをお勧めします。従来のスワップではコピーが発生するため、postblitコンストラクタとデストラクタが呼び出されます。移動は通常、プログラマーではなくコンパイラーによって行われます。ただし、の公式実装を見るとswap、可能な場合は取引から移動セマンティクスを取り除くためにいくつかのトリックを実行しているように見えます。とにかく、移動は通常コンパイラによって行われます。それらは、それが可能なことを知っているところでそれが行う最適化です(RVOはそれが可能な古典的なケースです)。

TDPL (p。251)によると、Dが移動が行われることを保証するケースは2つだけです。

  • すべての匿名の右辺値は、コピーではなく移動されます。this(thisソースが匿名の右辺値(つまり、上記の関数で紹介されている一時的なもの)の場合、)への呼び出しは挿入されませんhun
  • 関数内でスタック割り当てされてから返される名前付きの一時的なものはすべて、への呼び出しを省略しますthis(this)
  • 他の潜在的なエリジオンが観察されるという保証はありません。

したがって、コンパイラーは他の場所で移動を使用する場合がありますが、それが使用される保証はありません。

于 2011-07-30T23:12:05.350 に答える
3

私が理解する限りでは:

1)構造体が移動または構築されるのではなく、コピーされる場合。

2)移動セマンティクスのポイントは、2つのどちらも発生する必要がないということです。構造体の新しい場所は、構造体のビット単位のコピーで初期化され、古い場所はスコープ外になり、アクセスできなくなります。したがって、構造体はAからBに「移動」しました。

3)それは典型的な移動状況です:

S init(bool someFlag)
{
    S s;
    s.foo = someFlag? bar : baz;
    return s; // `s` can now be safely moved from here...
}

// call-site:
S s = init(flag);
//^ ... to here.
于 2011-07-30T18:26:22.047 に答える