unique_ptr swap不起作用

时间:2018-01-16 15:34:10

标签: c++ c++11 swap unique-ptr

我的代码是:

#include <memory>
#include <vector>

struct Core{
    Core(int n){} };

int main() {
    int base;
    std::vector<std::unique_ptr<Core>> cores;

    cores.push_back( std::move(std::unique_ptr<Core>(new Core(base))) );
    cores[0].swap(std::unique_ptr<Core>(new Core(base)));

    return 0;
}

我收到了这个错误:

  

|| === Build:Test in Release(编译器:GNU GCC编译器)=== |

     

在函数'int main()'错误中:没有匹配函数来调用'std :: unique_ptr&lt; Core&gt; :: swap(std :: unique_ptr&lt; Core&gt;)'

     

注意:候选人是:

     

注意:void std :: unique_ptr&lt; _Tp,_Dp&gt; :: swap(std :: unique_ptr&lt; _Tp,_Dp&gt;&amp;)[with_Tp = Core; _Dp = std :: default_delete&lt; Core&gt;]

     

注意:'std :: unique_ptr&lt; Core&gt;'中没有已知的参数1转换到'std :: unique_ptr&lt; Core&gt;&amp;'

3 个答案:

答案 0 :(得分:7)

你不能像这样交换临时对象(rvalue):

cores[0].swap(std::unique_ptr<Core>(new Core(base))); // error

但临时可以像这样

交换命名对象(lvalue
std::unique_ptr<Core>(new Core(base)).swap(cores[0]); // but this works

或者您可以直接设置值:

cores[0] = std::unique_ptr<Core>(new Core(base));

或(更好)使用std::make_unique

cores[0] = std::make_unique<Core>(base);

将对象构造函数的参数直接传递给std::make_unique函数。

如果您必须使用new,则始终存在std::unique_ptr::reset功能:

cores[0].reset(new Core(base));

答案 1 :(得分:2)

您使用std::move太多了。在您的情况下,移动会自动发生。所以,你可以写

cores.push_back( std::unique_ptr<Core>(new Core(base)) );
cores[0] = std::unique_ptr<Core>(new Core(base));

或者,使用std::make_uniquestd::unique_ptr::reset

cores.push_back( std::make_unique<Core>(base) );
cores[0].reset(new Core(base));

但是,如果您将unique_ptr作为本地变量,那么您必须使用std::move

std::unique_ptr<Core> p(new Core(base));
cores.push_back(std::move(p));

这与上面一样有效,但会创建一个可能不必要的局部变量。

答案 2 :(得分:1)

您需要使用左值std::unique_ptr<Core>进行交换,不允许使用未命名的临时值。

你能做的是

cores.push_back(std::unique_ptr<Core>(new Core(base))); // don't need move here
{
    std::unique_ptr<Core> other(new Core(base));
    cores[0].swap(other);
}