14

我想在我的类中有一个指向对象的指针向量。为了避免为它创建析构函数,我想使用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>'
}

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

4

3 回答 3

15

任何一个:

vec.push_back(std::move(ptr));

或者:

vec.emplace_back(createPtr(2));
于 2013-01-23T16:14:51.030 回答
15

考虑vec.push_back(). 它有两个重载,分别采用const std::unique_ptr<int>&or 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>左值引用(无论你是否将 && 放在它旁边,因为命名的右值仍然被视为左值)。左值永远不会隐式转换为右值(完全不安全)。但是您基本上可以通过使用std::move().

于 2013-01-23T19:43:27.773 回答
4

你有一个unique_ptr

std::unique_ptr<int> ptr = createPtr(2);

现在你把它的副本放在向量中:

vec.push_back(ptr);

现在您有两个unique_ptr具有相同值的 s。如果允许,它将不是唯一的。

于 2013-01-24T14:58:08.073 回答