请注意,由于您有一个 unique_ptr 向量,因此这些元素只能移动,即一旦您获得子集,原始向量将不再相同。
破坏性最小的方法是使用std::stable_partition将向量分成两组,同时将所有内容保持在同一个向量中:
auto sep = std::stable_partition(vec.begin(), vec.end(), [](const auto& foo) {
return foo->is_good();
});
// the part `vec.begin() .. sep` contains all "good" foos.
// the part `sep .. vec.end()` contains all "bad" foos.
如果顺序不重要,use std::partition instead。用法是一样的。
如果你想把坏的 foo 分割成另一个向量,你可以使用std::copy_if + std::make_move_iterator 将对象移出。请注意,这会在各处留下漏洞。使用std::remove 清理它们。
decltype(vec) bad_vec;
std::copy_if(std::make_move_iterator(vec.begin()),
std::make_move_iterator(vec.end()),
std::back_inserter(bad_vec),
[](const auto& p) { return !p->is_good(); });
auto new_end = std::remove(vec.begin(), vec.end(), nullptr);
vec.erase(new_end, vec.end());
如果您不再关心“坏”对象,请使用std::remove_if:
auto new_end = std::remove_if(vec.begin(), vec.end(), [](const auto& foo) {
return !foo->is_good();
});
vec.erase(new_end, vec.end());
// now `vec` only contains "good" foos.
如果您只想获取原始指针,而不是 unique_ptr 本身,您可以使用std::transform 填充vector<Foo*>,然后使用remove_if 过滤它...但此时可能是只是更容易编写 for 循环。
std::vector<int*> good_vec;
for (const auto& foo : vec) {
if (foo->is_good()) {
good_vec.push_back(foo.get());
}
}