Why there is no std::copy_if algorithm?

C++AlgorithmStl

C++ Problem Overview


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++0x, but a simple copy_if which takes a range, a output iterator and a functor would have been nice. Was it just simply missed out or is there some other reason behind it?

C++ Solutions


Solution 1 - C++

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)

Solution 2 - C++

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.

Solution 3 - C++

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);
          });

Solution 4 - C++

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.

Solution 5 - C++

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;
}

Solution 6 - C++

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 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNaveenView Question on Stackoverflow
Solution 1 - C++sbkView Answer on Stackoverflow
Solution 2 - C++rlbondView Answer on Stackoverflow
Solution 3 - C++Nikos AthanasiouView Answer on Stackoverflow
Solution 4 - C++Alex BView Answer on Stackoverflow
Solution 5 - C++alex tingleView Answer on Stackoverflow
Solution 6 - C++PatrykView Answer on Stackoverflow