unique_ptr 交换不起作用

unique_ptr swap doesn't work

我的代码是:

#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: Release in Test (compiler: GNU GCC Compiler) ===|

In function 'int main()' error: no matching function for call to 'std::unique_ptr<Core>::swap(std::unique_ptr<Core>)'

note: candidate is:

note: void std::unique_ptr<_Tp,_Dp>::swap(std::unique_ptr<_Tp,_Dp>&) [with_Tp = Core; _Dp = std::default_delete<Core>]

note: no known conversion for argument 1 from 'std::unique_ptr<Core>' to 'std::unique_ptr<Core>&'

您需要一个左值 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);
}

您使用 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));

这和上面的一样有效,但是创建了一个可能不需要的局部变量。

您不能像这样交换临时对象(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));