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