【发布时间】:2015-06-02 15:06:29
【问题描述】:
我正在尝试编写一个与 Python 的过滤器类似的就地过滤器函数。例如:
std::vector<int> x = {1, 2, 3, 4, 5};
filter_ip(x, [](const int& i) { return i >= 3; });
// x is now {3, 4, 5}
首先我尝试了这个:
template <typename Container, typename Filter>
void filter_ip(Container& c, Filter&& f)
{
c.erase(std::remove_if(c.begin(), c.end(), std::not1(f)), c.end());
}
但是,这不起作用,因为 lambdas don't have an argument_type field。
以下变体does work:
template <typename Container, typename Filter>
void filter_ip(Container& c, Filter&& f)
{
c.erase(std::remove_if(c.begin(), c.end(),
[&f](const typename Container::value_type& x) {
return !f(x);
}),
c.end());
}
但是,这似乎不太理想,因为以前,它只需要 Container 具有 begin、end 和 erase,而现在它还要求它定义一个 value_type。而且它看起来有点笨拙。
这是this answer 中的第二种方法。第一个将使用 std::not1(std::function<bool(const typename Container::value_type&)>(f)) 而不是 lambda,它仍然需要类型。
我还尝试将 arg func 指定为具有已知参数类型的 std::function:
template <typename Container, typename Arg>
void filter_ip(Container& c, std::function<bool(const Arg&)>&& f)
{
c.erase(std::remove_if(c.begin(), c.end(), std::not1(f)), c.end());
}
然后我得到:
'main()::<lambda(const int&)>' is not derived from 'std::function<bool(const Arg&)>'
有没有办法解决这个问题?直觉上看起来应该很简单,因为您需要做的就是将 not 应用于您已经知道 f 返回的布尔值。
【问题讨论】:
-
C++14 具有通用 lambda。它们很适合。
标签: c++ templates c++11 types lambda