7

C++ 標準ライブラリや Boost にはfilter、関数型言語に見られる関数に似たものがありますか?

私が見つけた最も近い機能はstd::remove_copy_if、私が望むものとは逆のことをしているようです。私の述語の否定されたバージョンを取得する関数はありますか( Haskellboost::lambdaと同様)? not述語を否定して、それを使用することができましstd::remove_copy_ifた。

filterC++ で関数を記述する方法を尋ねているわけではないことに注意してください。標準ライブラリやBoostがすでにそのような機能を提供しているかどうかを尋ねているだけです。

前もって感謝します。

4

4 に答える 4

6

Boost.Rangeには filter に相当するものがあります。
例を次に示します。

#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;
}
于 2010-09-03T11:51:28.307 に答える
6

<functional>forを含めてstd::not1試すcont.erase (std::remove_if (cont.begin (), cont.end (), std::not1 (pred ())), cont.end ());

于 2010-09-03T13:14:14.520 に答える
1

remove_iforremove_copy_ifnot1( で定義) とともに使用<functional>して、述語を反転します。このようなもの:

#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));
}
于 2010-09-03T14:17:05.803 に答える
1

機能的なスタイルのタスクの多くは、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()));

}
于 2010-09-03T13:23:49.823 に答える