C++11 将 unique_ptr 转换为基数 class

C++11 converting a unique_ptr to a base class

我有一个函数,它接受一些对象向量并对其进行过滤,并且需要 return 将过滤后的对象向量转换为基数 class。

class Base {
    // stuff
}

class Derived : public Base {
    // more stuff
}

// elsewhere...
vector<reference_wrapper<const unique_ptr<Base>>> do_something(const vector<unique_ptr<Derived>> &things) {
    vector<reference_wrapper<const unique_ptr<Base>>> a;

    for (const unique_ptr<Derived> &derived : things) {
        if (check(derived)) {
            a.push_back(derived);  // this obviously doens't work -
                                   // what should I put here?!

            // this does not work:
            // a.push_back(std::ref(derived.get()))
            // because derived.get() is an rvalue
        }
    }

    return a;
}

returned 向量不拥有任何原始对象 - 它们应该只是读者。原始对象的寿命将超过 returned 矢量的寿命。

我还没有看评论,所以可能已经有人回答了。然而,通常当 vector 不拥有其任何 pointed-to 成员时,不会使用对 unique_ptr 的引用——正如这所表达的那样,vector 应该能够使用unique_ptr只有所有者可以。

完整 observer 的常用方法是使用原始指针(至少在 observer_ptr 出现在标准库中之前)。约束是你永远不能调用 delete 或任何其他对这些指针的 memory-related 操作(这是 observer_ptr 设计不允许的)。

所以你写:

auto do_something(vector<unique_ptr<Derived>> const&things)
{
    vector<Base *> a;

    for (auto& derived : things) {
        if (check(derived))
        {
            a.push_back(derived.get());
        }

    return a;
}

与您选择对 const unique_ptr 的引用的情况的简短比较:unique_ptr interface 中的可调用 const 函数由 get()、[=19 给出=] 和 operator bool()。在这三者中,使用 vector<Base *> 方法你失去了调用 get_deleter() 的可能性。但是,因为只有一个reader,几乎可以肯定不需要删除器。

Scott Meyer(和他的参考资料)进行了稍微相关的讨论,您可能会感兴趣:http://scottmeyers.blogspot.de/2014/07/should-move-only-types-ever-be-passed.html