【问题标题】:"filter" higher order function in C++C ++中的“过滤”高阶函数
【发布时间】:2010-09-03 11:26:58
【问题描述】:

C++ 标准库和/或 Boost 是否有任何类似于函数式语言中的 filter 函数?

我能找到的最接近的函数是std::remove_copy_if,但它似乎与我想要的相反。 boost::lambda 是否有任何函数来获取我的谓词的否定版本(类似于 Haskell 中的 not)?我可以否定我的谓词并将其与std::remove_copy_if 一起使用。

请注意,我不是在问如何用 C++ 编写 filter 函数;我只是在问标准库和/或 Boost 是否已经提供了这样的功能。

提前致谢。

【问题讨论】:

  • std::remove_copy_if() 与您想要的相反吗?相反的对立面是什么?如果您只想删除元素,请使用 remove/erase idiom:container.erase (std::remove_if (container.begin (), container.end (), pred()), container.end ());
  • @wilx:我希望保留满足谓词的元素,并删除其他元素。

标签: c++ functional-programming higher-order-functions


【解决方案1】:

std::not1 包含<functional> 并尝试cont.erase (std::remove_if (cont.begin (), cont.end (), std::not1 (pred ())), cont.end ());

【讨论】:

  • 正是我想要的。谢谢! :-)
  • 啊,等等。我不希望原始集合发生突变。我想要一个新的修改副本。
  • @Missing Faktor:那么你想要remove_copy_if 而不是remove_if
【解决方案2】:

Boost.Range中有一个过滤器的等价物。
这是一个例子:

#include <vector>
#include <boost/lambda/lambda.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/range/adaptor/filtered.hpp>

using namespace boost::adaptors;
using namespace boost::lambda;

int main()
{
    std::vector<int> v = {3, 2, 6, 10, 5, 2, 45, 3, 7, 66};
    std::vector<int> v2;
    int dist = 5;

    boost::push_back(v2, filter(v, _1 > dist));
    return 0;
}

【讨论】:

    【解决方案3】:

    我发现很多函数式的任务可以通过结合 boost.iterators 来解决。为此,它有filter_iterator

    假设你有一个自然数向量,以及一个你想应用于一对迭代器的函数,它应该只看到过滤后的向量,只有奇数:

    #include <algorithm>
    #include <vector>
    #include <iterator>
    #include <numeric>
    #include <iostream>
    #include <boost/iterator/filter_iterator.hpp>
    template<typename Iter>
    void do_stuff(Iter beg, Iter end)
    {
        typedef typename std::iterator_traits<Iter>::value_type value_t;
        copy(beg, end, std::ostream_iterator<value_t>(std::cout, " "));
        std::cout << '\n';
    }
    struct is_even {
            bool operator()(unsigned int i) const { return i%2 == 0; }
    };
    int main()
    {
            std::vector<unsigned int> v(10, 1);
            std::partial_sum(v.begin(), v.end(), v.begin()); // poor man's std::iota()
    
            // this will print all 10 numbers
            do_stuff(v.begin(), v.end());
            // this will print just the evens
            do_stuff(boost::make_filter_iterator<is_even>(v.begin(), v.end()),
                     boost::make_filter_iterator<is_even>(v.end(), v.end()));
    
    }
    

    【讨论】:

      【解决方案4】:

      使用remove_ifremove_copy_if,与not1(在&lt;functional&gt; 中定义)反转谓词。像这样的:

      #include <algorithm>
      #include <functional>
      
      template <class ForwardIterator, class Predicate>
      ForwardIterator filter(ForwardIterator first, ForwardIterator last, 
                             Predicate pred)
      {
          return std::remove_if(first, last, std::not1(pred));
      }
      
      template <class InputIterator, class OutputIterator, class Predicate>
      OutputIterator filter_copy(InputIterator first, InputIterator last, 
                                 OutputIterator result, Predicate pred)
      {
          return std::remove_copy_if(first, last, result, std::not1(pred));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多