1

コピー不可、移動のみにしたい構造体がありますが、多くのPODが含まれているため、移動コンストラクターの記述は長くなり、変数を忘れるとデバッグが難しくなります。例:

struct myStruct{
    int a,b,c,d;
    double e,f,g,h;
    std::complex<double> value1,value2;

    std::unique_ptr<Calculator> calc;

    myStruct(){}
    myStruct(const myStruct &)=delete;
    myStruct(myStruct && other);
};

この種のムーブ コンストラクタの問題点は次のとおりです。

myStruct::myStruct(myStruct && other){
    std::memcpy(this,&other,sizeof(myStruct));
    other.calc.release();
    calc->rebind(this);
}

どのような問題に直面する可能性があり、これは明確に定義されていますか?

4

3 に答える 3

0

編集:最近の編集後、@Useless からの受け入れられた回答を好みます。以下は、移動コンストラクターをデフォルトとして定義できる代替アプローチを示すために残されていますが、これは受け入れられた回答と比較して過度に設計されています。

使用memcpyするのは悪い考えです。自明でない作業 (unique_ptr計算機の移動と再バインド) を行うヘルパー型を作成しmyStruct、それを で使用して、その移動操作をデフォルトにできるようにすることを検討するかもしれません。

struct RebindableCalc
{
  RebindableCalc();

  RebindableCalc(RebindableCalc&& r) noexcept : calc(std::move(r.calc))
  { calc->rebind(self()); }

  RebindableCalc& operator=(RebindableCalc&& r) noexcept
  {
    calc = std::move(r.calc);
    calc->rebind(self());
    return *this;
  }

  std::unique_ptr<Calculator> calc;

  myStruct* self();
};

struct myStruct : RebindableCalc
{
    int a,b,c,d;
    double e,f,g,h;
    std::complex<double> value1,value2;

    myStruct() = default;
    myStruct(myStruct&& other) = default;
    myStruct& operator=(myStruct&& other) = default;
};

inline myStruct* RebindableCalc::self()
{
  return static_cast<myStruct*>(this);
}

これにより、コンパイラは POD メンバーに最適なコードを生成し、メンバーに対しても正しいことを行うことができますunique_ptr<Calculator>。必要ありませんmemcpy。移動操作にさらにメンバーを追加しmyStructても、正しいことを行います。

于 2014-03-18T20:04:18.820 に答える