c++ - 如何模拟 remove_unless

标签 c++ c++11 c++14 erase-remove-idiom

我有代码可以从 std::vector<int> 中删除所有元素少于一些 int limit .我编写了一些部分应用 lambda 的函数:

auto less_than_limit = [](int limit) {
  return [=](int elem) {
    return limit > elem;
  };
};

auto less_than_three = less_than_limit(3);

当我用 std::vector<int> v{1,2,3,4,5}; 测试它时,我得到了预期的结果:

for(auto e: v) {
  std::cout << less_than_three(e) << " ";
}
// 1 1 0 0 0

我可以轻松删除所有少于三个的元素:

auto remove_less_than_three = std::remove_if(std::begin(v), std::end(v), less_than_three);

v.erase(remove_less_than_three, v.end());

for(auto e: v) {
  std::cout << e << " ";
}
// 3 4 5

如何使用 less_than_three 删除大于或等于 3 的元素? ?

我尝试包装 less_than_threestd::not1 ,但出现错误:

/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/stl_function.h:742:11: error: no type named 'argument_type' in 'struct main()::<lambda(int)>::<lambda(int)>'
     class unary_negate
           ^
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/stl_function.h:755:7: error: no type named 'argument_type' in 'struct main()::<lambda(int)>::<lambda(int)>'
       operator()(const typename _Predicate::argument_type& __x) const

/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/predefined_ops.h:234:30: error: no match for call to '(std::unary_negate<main()::<lambda(int)>::<lambda(int)> >) (int&)'
  { return bool(_M_pred(*__it)); }
                              ^

然后我尝试了 std::not1(std::ref(less_than_three)) ,但出现了这些错误:

/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/stl_function.h:742:11: error: no type named 'argument_type' in 'class std::reference_wrapper<main()::<lambda(int)>::<lambda(int)> >'
     class unary_negate
           ^
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/stl_function.h:755:7: error: no type named 'argument_type' in 'class std::reference_wrapper<main()::<lambda(int)>::<lambda(int)> >'
       operator()(const typename _Predicate::argument_type& __x) const
       ^
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/predefined_ops.h:234:30: error: no match for call to '(std::unary_negate<std::reference_wrapper<main()::<lambda(int)>::<lambda(int)> > >) (int&)'
  { return bool(_M_pred(*__it)); }
                              ^

如何取反 std::remove_if 中的函数不改变我的 lambda 的逻辑?换句话说,我如何模拟 remove_unless

最佳答案

not1 有点过时(并且要求仿函数提供某些成员类型定义,而 lambda 显然不提供)。

你必须自己写一个否定器:

auto negate = [] (auto&& f) {return [f=std::forward<decltype(f)>(f)] 
            (auto&&... args) {return !f(std::forward<decltype(args)>(args)...);};};

Demo .

关于c++ - 如何模拟 remove_unless,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34750561/

相关文章:

c++ - 模板类之外的内部类方法定义

c++ - 杀死和使用 waitpid 进行收获的能力之间的预期持续时间

c++ - std::vector 大小?

c++ - C++11 的编译器标志 - 找不到计时文件

c++ - 将 QPixmaps 拖入 QGraphicsScene : how to avoid 'auto' not allowed in lambda parameter

c++ - 是否可以覆盖运算符?

c++ - 无法在 C++ 中以字节模式读取二进制文件

c++ - 初始化指向多维数组的动态指针的正确方法?

c++ - 如何在 C 中重现 C++ 类样式的 get 函数?

c++ - 在 Ogre3d 中创建手动网格?