【发布时间】:2018-08-07 13:54:16
【问题描述】:
我有一个vector 或list,我只想将代码应用于特定元素。例如
class Container : public std::vector<Element*>
或者
class Container : public std::list<Element*>
还有:
Container newContainer = inputContainer.Get(IsSomething);
if (!newContainer.empty()) {
for (Element* const el: newContainer ) {
[some stuff]
}
} else {
for (Element* const el : inputContainer) {
[some stuff]
}
}
我写了一个成员函数Get()如下。
template<typename Fn>
auto Container::Get(const Fn& fn) const {
Container output;
std::copy_if(cbegin(), cend(), std::inserter(output, output.end()), fn);
return output;
}
而IsSomething 将是一个 lambda,例如
auto IsSomething= [](Element const* const el)->bool { return el->someBool; };
从性能的角度来看:这是一个好方法吗?还是复制删除比较好?
template<typename Fn>
auto Container::Get(const Fn& fn) const {
Container output(*this);
output.erase(std::remove_if(output.begin(), output.end(), fn), end(output));
return output;
}
或者有更好的方法吗?
编辑:不同的例子
由于我之前的示例可以用更好的方式编写,让我们展示一个不同的示例:
while (!(container2 = container1.Get(IsSomething)).empty()&&TimesFooCalled<SomeValue)
{
Container container3(container2.Get(IsSomething));
if (!container3.empty()) {
Foo(*container3.BestElement());
} else {
Foo(*container2.BestElement());
}
}
【问题讨论】:
-
你想要
back_inserter。output.end()将在插入第一个元素后立即失效。 -
如果你想要性能我建议你看看this
-
是的。它适用于任何提供
push_back方法的东西。std::vector和std::list都可以。 -
子类化容器是个好主意吗?我认为这不是一个好主意stackoverflow.com/questions/6806173/…
-
@JHBonarius 请看我的扩展答案。