yohhoyの日記

2012-06-16

ムーブの跡

C++11におけるムーブされた後のオブジェクト状態についてメモ。

C++11標準規格ではムーブ後のオブジェクト状態について、下記2種類の型に対する要求を規定する。N3264のRationale参照*1

  • [A] 標準ライブラリが提供する型
  • [B] 標準ライブラリと組み合わせて利用するユーザ定義型*2

[B]ユーザ定義型に対しては[A]標準ライブラリ提供型に比べて弱い要求条件、つまり標準アルゴリズムが正常動作するために必要最低限の保証しか要求しない*3。ただし[A]に対する要求はムーブセマンティクスにおける“ベストプラクティス”と捉えることができ、ムーブ操作に対応するユーザ定義型でもこのレベルを保証する事が望ましい。

標準ライブラリ提供型

標準ライブラリ提供型において、ムーブ後のオブジェクトは“有効だが未規定な状態(valid but unspecified state)”となる。

N3337 17.3.26, 17.6.5.15より引用。

valid but unspecified state
an object state that is not specified except that the object's invariants are met and operations on the object behave as specified for its type
[Example: If an object x of type std::vector<int>; is in a valid but unspecified state, x.empty() can be called unconditionally, and x.front() can be called only if x.empty() returns false. -- end example]

Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.


一部の標準ライブラリ提供クラス(テンプレート)では、ムーブ後のオブジェクト状態についてより詳細に規定する。

クラスムーブ後のオブジェクト状態
unique_ptrポインタを所有しない(20.7.1/p4, 20.7.1.2.1/p16)
shared_ptrポインタを所有しない(20.7.2.2/p1, 20.7.2.2.1/p22)
unique_lockMutexと関連づけられずロック保持しない(30.4.2.2.1/p21)
promiseShared stateを所有しない(30.6.5/p6)
futureShared stateを所有しない(30.6.6/p8)
shared_futureShared stateを所有しない(30.6.7/p10)
packaged_taskShared stateを所有しない(30.6.9.1/p6)


ユーザ定義型

標準アルゴリズムと組み合わせるユーザ定義型において、ムーブ後のオブジェクト状態は“未規定(unspecified)”を要求する。言い換えると、標準アルゴリズムが求める要件さえ満たしていれば、ユーザ定義型にはそれ以上の追加条件が要求されない。

N3337 17.6.3.1のMoveConstructible要件、MoveAssignable要件より該当箇所を引用。rvはムーブ後のオブジェクトを表す。

rv's state is unspecified. [Note: rv must still meet the requirements of the library component that is using it. The operations listed in those requirements must work as specified whether rv has been moved from or not. -- end note]



関連URL

*1N3264 CH-18 and US-85: Clarifying the state of moved-from objects (Revision 1)

*2:標準ライブラリと組み合わせて利用しないユーザ定義型については、端的にいうとC++11標準では何も要求しない。ムーブ操作はC++の言語仕様ではなくセマンティクスに過ぎないため、標準ライブラリと相互作用しないユーザ定義型にどのようなセマンティクスを持たせるかについて、C++標準規格では何ら規定せずプログラマにゆだねている。

*3:例えばMoveConstructible要件のみを要求する標準アルゴリズムと組み合わせるユーザ定義において、ムーブ後のオブジェクトがデストラクトさえ不可能な状態となっても良い。この場合のユーザ定義型に対する破棄操作はユーザ側の責任であり、C++標準ライブラリはそこに関与しない。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/yohhoy/20120616/p1
リンク元