【问题标题】:How to use std::find_if with a vector of unique pointers?如何将 std::find_if 与唯一指针向量一起使用?
【发布时间】:2021-04-02 10:46:52
【问题描述】:

您如何将std::find_if 之类的算法与唯一指针向量一起使用?例如:

#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>

class Integer {
public:
    explicit Integer(int i): i_(i){};

    int get() const{
        return i_;
    }

private:
    int i_;
};

using IntegerPtr = std::unique_ptr<Integer>;

int main() {
    IntegerPtr p1 = std::make_unique<Integer>(4);
    IntegerPtr p2 = std::make_unique<Integer>(5);
    IntegerPtr p3 = std::make_unique<Integer>(6);
    std::vector<IntegerPtr> vectorOfIntegerPointers({
        std::move(p1),
        std::move(p2),
        std::move(p3),
    });

    int i = 5;

    auto first_index_larger_than_i = std::find_if(vectorOfIntegerPointers.begin(), vectorOfIntegerPointers.end(), [&](IntegerPtr s) {
        return s->get() > i;
    });

    std::cout << first_index_larger_than_i.get() << std::endl;

    return 0;
}

失败

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1881:31: error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<Integer, std::__1::default_delete<Integer> >'
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
                              ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

【问题讨论】:

  • 糟糕,谢谢。
  • @Galik 我已经尝试过这种变化,但我得到了同样的错误
  • std::move(p1) 将 unqiue_ptr 移动到初始化列表中,但是当调用带有初始化列表的向量的 ctor 时,它会尝试复制列表的所有 unique_ptrs,这是不可能的,因为无法复制 unique_ptr。
  • 啊啊我明白了,所以初始化列表不能与unique_ptrs 一起使用。很高兴知道。感谢您的所有建议,我现在可以正常工作了。如果您发布答案,很高兴接受答案。

标签: c++ algorithm unique-ptr


【解决方案1】:

代码中有两个问题都导致试图复制不可复制的unique_ptr

  1. unique_ptr 不能传递给vector(initializer_list) 构造函数,因为initializer_list 将其元素包装为const 对象,并且const 对象不能被移出。所以移动构造函数不参与重载决议,只留下复制构造函数作为候选者,后来编译失败并出现您看到的错误:“调用隐式删除的复制构造函数”。

    所以你必须使用另一种解决方案来构造vector&lt;unique_ptr&gt;,例如使用push_back

     std::vector<IntegerPtr> vectorOfIntegerPointers;
     vectorOfIntegerPointers.push_back(std::make_unique<Integer>(4));
     vectorOfIntegerPointers.push_back(std::make_unique<Integer>(5));
     vectorOfIntegerPointers.push_back(std::make_unique<Integer>(6));
    

    或者编写一个包装器将unique_ptr 保存为mutable 成员(example)。

  2. [&amp;](IntegerPtr s) { ... } 用于std::find_if 尝试按值获取unique_ptr 的实例。但是unique_ptr 是不可复制的,因此同样的错误。

    一个快速的解决方法是通过引用来代替:

    [&amp;](IntegerPtr const&amp; s) { ... }

【讨论】:

    猜你喜欢
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    相关资源
    最近更新 更多