yohhoyの日記

技術的メモをしていきたい日記

ムーブ不可&コピー不可なオブジェクトを扱う

C++11でムーブもコピーもできないオブジェクトを扱う方法についてメモ。(エッセンスのみ。詳説は元記事を)

実は C++0x では、こういう「コピーもムーブも出来ないオブジェクト」であっても、 uniform initialization を使えば、関数から返すことができるようになったのです:

person make_charactor()
{
  return { "Chiffon Schroedinger", 14 };
}

これを行うには、「該当するコンストラクタが explicit 指定されていないこと」という条件こそありますが、コピー出来る/出来ない、ということに関しては、特に条件はありません。

http://d.hatena.ne.jp/gintenlabo/20101211/1292088788

Uniform initialization@return文+rvalue reference型による変数束縛を用いる。

class X {
public:
  X(const char *s, int n);
  ~X();
  // コピー不可
  X(const X&) = delete;
  X& operator(const X&) = delete;
  // ムーブ不可
  X(XX&) = delete;
  X& operator(XX&) = delete;

  void do_something();
};

X func()
{
  return {"foobar", 42};  // ★ 呼び出し元でオブジェクトXを構築
}

int main()
{
  X x1;
  X xc(x1);            // NG: コピー不可
  X xm(std::move(x1)); // NG: ムーブ不可

  func();                 // OKだが...ほぼ無意味
  func().do_something();  // OK

  X x2(func());     // NG: x2へのムーブ操作が必要
  X&& x3 = func();  // OK: rvalue参照で戻り値(prvalue)を束縛

  //...

} // x3が束縛するオブジェクト=func()が作成したオブジェクトはここで破棄

N3337 6.6.3/p2, 13.3.1.7/p1より対応箇所のみ引用。

2 (snip) A return statement with a braced-init-list initializes the object or reference to be returned from the function by copy-list-initialization (8.5.4) from the specified initializer list. [ Example:

std::pair<std::string,int> f(const char* p, int x) {
  return {p,x};
}

-- end example ]

1 (snip) In copy-list-initialization, if an explicit constructor is chosen, the initialization is ill-formed.

関連URL