在推入std :: vector时,std :: unique_ptr的正确用法是什么

Mir*_*pas 12 c++ vector unique-ptr c++11

我希望有一个指向我班级中对象的指针.为了避免为它做一个析构函数我想使用std::unique_ptr,因为在我的类中创建/拥有/破坏对象,但是我有一个我无法理解的编译器错误.下一个代码将作为我的问题的简短示例:

std::unique_ptr<int> createPtr(int value)
{
    std::unique_ptr<int> ptr(new int(value));
    return ptr;
};

int main()
{
    std::vector<std::unique_ptr<int>> vec;
    vec.push_back(createPtr(1));

    std::unique_ptr<int> ptr = createPtr(2);
    vec.push_back(ptr);//error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
}
Run Code Online (Sandbox Code Playgroud)

能否请您解释一下为什么我会收到此错误以及正确的用法是std::unique_ptr什么?

Ker*_* SB 14

或者:

vec.push_back(std::move(ptr));
Run Code Online (Sandbox Code Playgroud)

要么:

vec.emplace_back(createPtr(2));
Run Code Online (Sandbox Code Playgroud)

  • @Felics问题是`unique_ptr`不允许复制构造,因此试图`push_back``ptr`失败,因为它试图调用复制构造函数.但是,移动构造函数是可访问的,并且Kerrek的两个解决方案都调用它而不是复制构造函数. (7认同)
  • 它解决了问题,但你能解释一下问题吗? (2认同)

Red*_*III 12

考虑一下vec.push_back().它有两个重载,需要const std::unique_ptr<int>&std::unique_ptr<int>&&.永远不能使用第一个过载.这是因为vector<>要求类型可分配或可移动(C++ 11添加).'可转让'意味着复制.push_back(const T&)将尝试将传入值复制(分配)到容器末尾的新空间.std::unique_ptr<>表示由单个所有者拥有的资源.通过复制它(指针),将出现多个所有者.因为那unique_ptr是不可复制的.

说完了所有这些,你只能使用T&&过载.

createPtr()返回std::unique_ptr<int>,但由于这是临时结果(函数返回值),因此它被视为右值引用(隐式).这就是为什么可以使用它.

ptr只是一个std::unique_ptr<int>左值引用(无论你是否将&&放在它旁边,因为命名的 rvalues仍然被视为左值).Lvalue永远不会被隐式转换为rvalue(完全不安全).但你基本上可以告诉编译器"好的,你可以把我传递给你的对象拿走,并且我保证我不会期望这个参数保持不变" std::move().