【问题标题】:unique_ptr with standard containers: attempting to reference a deleted function具有标准容器的 unique_ptr:尝试引用已删除的函数
【发布时间】:2015-05-01 10:40:38
【问题描述】:

我正在尝试将 unique_ptr 与任何 stl 容器一起使用(实际上 list 更适合我),我看到 unique_ptr 需要移动语义。 这段代码,其中员工是基类:

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;
}

你明白我在做什么 - 只是从函数中返回这个列表

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

【问题讨论】:

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


    【解决方案1】:

    您正在尝试使用带有std::initializer_list&lt;p_employee&gt; 参数的std::list 构造函数来构造std::list&lt;p_employee&gt;

    不幸的是,std::initializer_list 只允许const 访问其元素,这意味着编译器将尝试复制每个失败的p_employee(或std::unique_ptr&lt;employee&gt;),因为unique_ptr 是仅移动类型并且无法复制。

    如果您将 braced-init-list 替换为一系列 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.我想过,但懒得编辑。应该知道有人会打电话给我:)
    • 非常感谢,我知道正确的就地构造,但错误地阅读了错误 - 我认为错误消息是在“return objects;”行生成的。你会如何为 std:array 做同样的事情?
    • @amigo421 std::array 是一个聚合,因此您可以使用大括号来执行原始示例中的初始化,因为在这种情况下它将是聚合初始化,并且不会复制 unique_ptrs被尝试。或者,您可以在array 中默认构造unique_ptrs,然后使用unique_ptr::reset 或其移动赋值运算符添加元素 - coliru.stacked-crooked.com/a/9f71df479b4124f3
    猜你喜欢
    • 2020-05-02
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    • 2017-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多