2011-12-12 113 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; 
} 

上面的示例将一个元素移出矢量,但矢量的大小保持不变。什么包含被移动的矢量元素?

什么包含移动后移动的元素?访问该元素是不是一个未定义的行为?它是nullptr(该示例打印它为空)?

回答

5

这与矢量无关。 std::uniqe_ptr定义移动后对象的状态,它被设置为空(20.7.1/4)。

通常,已经移动的对象具有有效但未指定的状态。因此,除非类型记录无法访问的情况,否则您可以访问它。特别班按理说应该给那个状态尽可能的详细,但什么矢量依靠的是:

  1. 对象可以再次(否则载体将无法重新分配)
  2. 的移动当矢量被销毁时,对象仍然可以被销毁。

因此,在矢量比unique_ptr其他类型的,你应该觉得自己所得到的移动源的值可以是任何的:

  1. “空”或该类型的“零”值,
  2. 原始值,
  3. 目标移动的的原始值,
  4. ,你没瘦类型的其他值k的。

如果你仍然认为这是值得访问可能是任何的值,继续;-)

+0

这样做的理由是,移动的元素必须是在破坏的状态。 –

+0

+1。虽然,我敢说,一个移动任务不应该等同于一个交换,因为这可能会让一些资源分配一段意想不到的时间。所以,案例(3)不是我所期望的。 – sellibitze

+1

@sellobitze:不,我不打算将其作为一种常见做法的例子,就像某些合法的事情一样,因此如果事情真的发生,您也无法对此感到愤怒。 –