15

私はVS11を使用し、以下を使用します:

class ContextWrapper
{
public:

    ContextWrapper()
    {
    } //it should be defaulted I *guess* in order to have automatic move constructor ?
      // no support in VS11 for that now  

    Context* GetContext()
    {
        return this->context.get();
    }

    void SetContext(std::unique_ptr<Context> context)
    {
        this->context = std::move(context);
    }

    //ContextWrapper(ContextWrapper&& other):  context(std::move(other.context))
    //{
    //} // I would like this to be generated by the compiler

private:
    ContextWrapper(const ContextWrapper&);
    ContextWrapper& operator= (const ContextWrapper&);

    std::unique_ptr<Context> context;
};

このクラスでムーブ コンストラクター/代入を生成したいと思います。自明なコンストラクターを持っていないという事実は、私が動かない理由ですか? それとも、これに影響を与える他の要因がありますか?

4

2 に答える 2

23

C ++ 11のこの部分は、残念ながら流動的です。そして、標準が何を言おうとも、VC11はまだそれを実装できなかったでしょう。ですから、今日は、生成されたムーブメンバーを信頼できるとは思いません。

しかし、これは良い質問であり、私はそれについて良い答えを得たいと思いました。

一般に、ユーザーが宣言したコピーメンバーやデストラクタがない場合、コンパイラは移動メンバーを生成する必要があります。 = defaultユーザーが宣言したものとして= deleteカウントされます。一方の移動メンバー(移動コンストラクターなど)を宣言した場合、もう一方は暗黙的に生成されません。

残念ながら、C ++ 11は、で宣言されたときに移動メンバーが暗黙的に削除される場合が=defaultあり、それらの生成は、ベースとメンバーが移動メンバーを持っているか、簡単にコピー可能であるかによって異なる場合があると続けています。これは非常に複雑で、驚くべき動作をすることがあります。このバグを追跡するCWGの問題は次のとおりです。

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1402

私がこれを書いているとき、問題は正しい提案された解決策を持っていません。約1週間で変わると思います。オレゴン州ポートランドで開催された2012年秋のC++標準会議で、基本的に次のような合意に達しました。

  1. コンパイラーは、moveメンバーを暗黙的に削除することはありません。
  2. 移動メンバーの暗黙的な生成は、常にと同じものになり= defaultます。
  3. 暗黙の生成は、基地やメンバーの些細なことや、移動したときに投げることができるかどうかに依存しません。

一言で言えば、CWG1402の修正された表現は単純に次のように言うことを期待しています。

一般に、ユーザーが宣言したコピーメンバーやデストラクタがない場合、コンパイラは移動メンバーを生成する必要があります。 = defaultユーザーが宣言したものとして= delete カウントされます。一方の移動メンバー(移動コンストラクターなど)を宣言した場合、もう一方は暗黙的に生成されません。また、=defaultメンバーを移動すると、各ベースとメンバーを移動するものが得られます。

(適切に標準化して)。私はこれを言う言葉遣いをまだ見ていません。ジェイソンメリルは私たちのためにそれを書いています。

これは、コンパイラがスローする移動メンバーを暗黙的に生成する場合があることを意味します。しかし、私たちは単純なルールを求めていましたが、それでもほとんどの場合正しいことをしていました(驚くことはほとんどありません)。

于 2012-11-01T15:26:16.177 に答える