使用标准容器的unique_ptr:尝试引用已删除的函数

3

我正在尝试将unique_ptr与任何STL容器(实际上我更喜欢使用list)一起使用,我发现unique_ptr需要移动语义。 以下是一个示例代码,其中employee是基类:

typedef std::unique_ptr<employee> p_employee;

std::list<p_employee> make_test_array() {
    std::list<p_employee> objects = {
       p_employee(new accounter(...)),
       p_employee(new engineer(...)),
       p_employee(new developer(...))
    };

    return objects;
}

你看我想做什么 - 只是从函数中返回这个列表

那么有没有能力做到这一点?什么是正确的技术?

1个回答

4
您正在尝试使用接受std :: initializer_list < p_employee>参数的std :: list构造函数构建std :: list <p_employee>

不幸的是,std :: initializer_list仅允许对其元素进行const访问,这意味着编译器将尝试复制每个p_employee(或std :: unique_ptr< employee>),但是由于unique_ptr是一种只能移动而不能复制的类型,所以会导致失败。

如果您用一系列emplace_back / push_back调用来替换大括号初始化列表,则代码应该可以正常工作。

std::list<p_employee> make_test_array() {
    std::list<p_employee> objects;

    objects.emplace_back(new accounter(...));
    objects.push_back(p_employee(new engineer(...))); // the exception safe alternative
    // and so on

    return objects;
}

@T.C. 我想过,但懒得编辑。早该知道会有人指出 :) - Praetorian
非常感谢,我知道正确的就地构造方式, 但是我错误地读取了错误 - 我认为错误消息是在“return objects;”行生成的。 您如何为std:array执行相同的操作? - amigo421
@amigo421 std::array 是一个聚合体,因此您可以使用大括号来执行初始化,就像您原始示例中的那样,因为在这种情况下它将是聚合初始化,并且不会尝试复制 unique_ptr。 或者,您可以在 array 中默认构造 unique_ptr,然后使用 unique_ptr::reset 或其移动赋值运算符添加元素 - http://coliru.stacked-crooked.com/a/9f71df479b4124f3 - Praetorian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接