2011-12-12 6 views
2
#include <vector> 
#include <iostream> 
#include <memory> 

int main() 
{ 
    // create the vector 
    std::vector< std::unique_ptr<int> > v; 
    for (int i = 0; i < 5; ++ i) 
    { 
     std::unique_ptr<int> newItem(new int(i)); 
     v.push_back(std::move(newItem)); 
    } 

    std::cout<<"vector's size before the move = " << v.size() << std::endl; 

    // move one item 
    auto it = move(v[2]); 
    std::cout<<"moved element = " << *it << std::endl; 
    std::cout<<"vector's size after the move = " << v.size() << std::endl; 
if (nullptr == v[2].get()) 
    std::cout<<"it is nullptr" << std::endl; 
} 

上記の例では、ベクトルから1つの要素を移動していますが、ベクトルのサイズは変わりません。移動するベクトルの要素は何に含まれていますか?

移動後に移動した要素は何になりますか?その要素にアクセスするのは未定義の動作ですか?それはnullptrですか(この例ではnullが出力されます)。

答えて

5

これはベクターとは関係ありません。 std::uniqe_ptrは、移動後のオブジェクトの状態を定義します。ヌル(20.7.1/4)に設定されています。

一般に、移動元のオブジェクトには有効なが未指定の状態があります。そのため、アクセスできない型のドキュメントの場合はアクセスできます。可能な限り特定のクラスは、おそらくその状態の詳細を与える必要があり、しかしベクターが依存することである。オブジェクトが再びから移動することができる

  1. (さもなければベクトルが再割り当てすることができないだろう)
  2. ベクトルが破壊されたときにオブジェクトを破壊することができます。

    1. 「空」か:

    だから、ベクトルでunique_ptr以外のタイプのために、あなたはおそらく、移動のソースの結果の値は、のいずれかとすることができることを自分自身に考えなければなりませんタイプの「ゼロ」値、

  3. 元の値、
  4. ターゲット移動のの元の値、あなたが薄いなかったタイプの
  5. 他の値〜のk。

あなたはまだそれがそれらのいずれかであるかもしれない値にアクセスする価値だと思う場合は、先に;-)

+0

を行くこの背後にある論理的根拠が移動要素が破壊可能な状態でなければならないということです。 –

+0

+1。しかし、私は移動割り当てがスワップと同等ではないと言うことを敢えて言います。これは、予期せず長い時間の間に割り当てられたリソースを残す可能性があるためです。だから、ケース(3)は私が期待するものではありません。 – sellibitze

+1

@sellobitze:いいえ、私は、それが正当なものと同じように一般的な慣行の例になることを意図していなかったため、もし起こった場合にそれに憤慨する権利はありません。 –