Why there is no std::copy_if algorithm?

后端 未结 6 1191
无人共我
无人共我 2020-12-03 04:23

Is there any specific reason for not having std::copy_if algorithm in C++ ? I know I can use std::remove_copy_if to achieve the required behavior. I think it is coming in C+

相关标签:
6条回答
  • 2020-12-03 04:36

    Multiple sources indicate that it was left out of STL by accident.

    However, I am not sure if that's a fact or a self-perpetuating myth. I'd appreciate if anyone would point out a source more credible than a link to a random post on the Internet.

    0 讨论(0)
  • 2020-12-03 04:41

    Stroustrup says they forgot it. It's in C++11.

    However, you can use remove_copy_if (which really should be called copy_if_not) along with not1 instead.

    0 讨论(0)
  • 2020-12-03 04:41

    Just for completeness I will add that boost has boost::algorithm::copy_if for those of you who cannot use c++11's version (like me) in boost/algorithm/cxx11/copy_if.hpp which will use std::copy_if when:

    #if __cplusplus >= 201103L
    //  Use the C++11 versions of copy_if if it is available
    using std::copy_if;         // Section 25.3.1
    #else
    

    Example:

    #include <boost/algorithm/cxx11/copy_if.hpp>
    #include <boost/assign/list_of.hpp> // for 'list_of()'
    #include <boost/foreach.hpp>
    
    #include <iostream>
    #include <vector>
    #include <iterator>
    
    struct Odd
    {
      bool operator()(int n)
      {
        return n & 1;
      }
    };
    
    int main()
    {
      std::vector<int> v = boost::assign::list_of(0)(1)(2)(3)(4);
      BOOST_FOREACH(int i, v)
        std::cout << i << ' ' ;
    
      std::vector<int> out;
      boost::algorithm::copy_if(v.begin(), v.end(), std::back_inserter(out), Odd());
    
      std::cout << std::endl;
    
      BOOST_FOREACH(int i, out)
        std::cout << i << ' ' ;
    
    }
    

    Output:

    0 1 2 3 4 
    1 3 
    
    0 讨论(0)
  • 2020-12-03 04:43

    According to Stroustrup's "The C++ Programming Language" it was just an over-sight.

    (as a citation, the same question answered in boost mail-lists: copy_if)

    0 讨论(0)
  • 2020-12-03 04:51

    Just for completeness, in case someone googles his/her way to this question, it should be mentioned that now (post C++11) there is a copy if algorithm. It behaves as expected (copies the elements in a range, for which some predicate returns true, to another range).

    A typical use case would be

    std::vector<int> foo{ 25, 15, 5, -5, -15 };
    std::vector<int> bar;
    
    // copy only positive numbers:
    auto it = std::copy_if (foo.begin(), foo.end(), std::back_inserter(bar), 
                [](int i){return !(i<0);
              });
    
    0 讨论(0)
  • 2020-12-03 05:01

    It's dead easy to write your own:

    template <class InputIterator, class OutputIterator, class Predicate>
    OutputIterator copy_if(InputIterator first, InputIterator last,
                           OutputIterator result, Predicate pred)
    {
      return std::remove_copy_if(first,last,result,std::not1(pred));
    }
    

    Edit: This version works with all predicates:

    template <class InputIterator, class OutputIterator, class Predicate>
    OutputIterator copy_if(InputIterator first, InputIterator last,
                           OutputIterator result, Predicate pred)
    {
      while(first!=last)
      {
        if(pred(*first))
            *result++ = *first;
        ++first;
      }
      return result;
    }
    
    0 讨论(0)
提交回复
热议问题