2017-02-03 57 views
3

表现在下面的代码,在foo断言失败:移动语义出乎意料

void bar (std::shared_ptr<int> && value) { 
} 

void foo() { 
    auto ptr = std::make_shared<int>(5); 
    bar(std::move(ptr)); 
    assert(ptr == nullptr); 
} 

共享指针仍然指向呼叫到bar后的值5。我期望拨打bar的电话使用移动语义,并将ptr留空。

我的理解缺陷在哪里?

+1

你在哪里期待它移动到什么呢? – Galik

+0

'std :: move()'声明:'template < class T > constexpr typename std :: remove_reference :: type && move(T && t);'返回值:'static_cast :: type &&>(t)'用法完美转发,通过引用或右值引用采用't',并将其转换为右值引用。 –

回答

5

执行实际移动后指针将变为空。 std::move本身不会移动任何东西。它简单地使得将名为对象ptr传递给右值参考预期函数成为可能。

由于您实际上没有在该功能(或任何其他位置)内移动任何内容,因此指针始终保持不动。

做到这一点(对于一个例子)

void bar (std::shared_ptr<int> && value) { 
    std::shared_ptr<int> another_ptr(std::move(value)); 
} 

,你会看到你原来的指针移动。

8

基本上,std::move()只是一个演员。

更改bar()可以查看您想要的结果。

void bar (std::shared_ptr<int> && value) 
{ 
    std::shared_ptr<int> v{std::move(value)}; 
}