remove_if来自带有成员函数的共享指针的std :: vector

时间:2017-03-10 16:28:36

标签: c++ c++11 smart-pointers idioms

如何删除std::vector<std::shared_ptr<PTile>> ptiles满足条件ptile->hasNoRegions()的元素?我一直在尝试使用remove_if,但Predicate使用对象的数据成员,而不是指针。如果元素是指向对象的智能指针,如何将谓词设置为函数?

目前我所拥有的

    ptiles.erase(std::remove_if(ptiles.begin(), ptiles.end(), &PTile::hasNoRegions), ptiles.end());

其中hasNoRegionsPTile的成员函数。这显然不起作用,因为我有std::shared_ptr<PTile>,而不是PTile

我正在使用MSVC 2013。

2 个答案:

答案 0 :(得分:4)

即使向量不存储指针,这可能也不会起作用,因为成员函数将this作为隐式参数,并且代码不会生成。

您需要编写一个显式处理std::shared_ptr的函子或lambda。

ptiles.erase(
    std::remove_if(ptiles.begin(), ptiles.end(), [](std::shared_ptr<PTile> const& ptr) {
        return ptr->hasNoRegions();
    }), 
    ptiles.end()
);

另外,如果你没有lambdas:

//Outside method
bool should_remove_ptile(std::shared_ptr<PTile> const& ptr)  {
    return ptr->hasNoRegions();
}

//inside method

ptiles.erase(std::remove_if(ptiles.begin(), ptiles.end(), should_remove_ptile), ptiles.end());

答案 1 :(得分:2)

  

我一直在尝试使用remove_if,但Predicate使用对象的数据成员,而不是指针。

什么指针?您将需要使用lambda,因为不支持传递成员函数指针:

ptiles.erase(std::remove_if(ptiles.begin(), ptiles.end(), [](const auto& value) {
    return value->hasNoRegions();
}), ptiles.end());

请注意,MSVC 2013的现代C ++支持较差,因此您可能需要编写一个函子而不是lambda,或者不要在lambda中使用auto