【问题标题】:Lambda expression taking an unique pointer contained in a vectorLambda 表达式采用向量中包含的唯一指针
【发布时间】:2017-11-20 17:22:02
【问题描述】:

我有一个向量 foos 指向我的资源类型 Foo 的唯一指针。我想删除其中一些满足给定条件的内容。我该怎么做?

class Foo
{
public:
    int some_num;
    Foo(int some_num_) :some_num{ some_num_ }
    {}
    int getNum()
    {
        return some_num;
    }
};

using FooPtr = std::unique_ptr<Foo>;
using Foos = std::vector<FooPtr>;

int main()
{
    Foos foos;
    foos.push_back(std::move(std::make_unique<Foo>(30)));
    foos.push_back(std::move(std::make_unique<Foo>(35)));
    std::vector<int> some_nums = { 35, 30, 25 };
    for each (auto& num in some_nums)
    {
        foos.erase(std::remove_if(foos.begin(), foos.end(), 
             [&](auto foo) {return num == foo->getNum(); }), foos.end());
    }
    return 0;
}

看起来我正在复制unique_ptr,所以我收到以下错误,

'std::unique_ptr<Foo,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function

我应该怎么做?我不会使用该资源。我不关心超出这一点的所有权。

【问题讨论】:

  • s/for each (auto&amp; num in some_nums)/for(auto&amp; num : some_nums)
  • 为什么要将std::remove_if的返回值传递给std::vector::erase?根据documentation,返回值是“新值范围的结束迭代器”您真的是要删除此类迭代器指向的元素吗,此外到满足 lambda 的值?
  • @AlgirdasPreidžius 我想这被称为擦除删除习语。同样来自手册 herehere:“调用 remove 之后通常调用容器的擦除方法,该方法擦除未指定的值”...,“指向新逻辑端之间元素的迭代器并且范围的物理末端仍然是可解引用的,但元素本身具有未指定的值", "迭代器 pos 必须有效且可解引用。"
  • @user3222 在复制的 sn-p 状态中,应该自己调用erase?您刚刚复制了所述过程的描述。
  • @AlgirdasPreidžius 我确实提到“我想删除其中一些满足给定条件的文件”。所以,我应该从我的容器中删除这些元素,不是吗?

标签: c++ visual-c++ lambda unique-ptr erase-remove-idiom


【解决方案1】:

auto 推演规则将推演类型为std::unique_ptr,强制复制。所以只要把lambda表达式的参数类型改成

[&](const auto& foo) {return num == foo->getNum(); })

【讨论】:

  • 假设eachin 被定义为适当的宏。
  • 我认为 user3222 的意图很明显。这很可能只是一些示例,而不是导致此特定错误的实际代码。
  • @user0042 他们不必是宏。见msdn.microsoft.com/en-us/library/ms177202.aspx
  • @Default OP 是否提到了他们使用 MSVC 的任何地方?
  • @user0042 感谢您的评论。我应该提前提到的。我使用 MSVC。
猜你喜欢
  • 1970-01-01
  • 2014-04-02
  • 2018-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多