Why is there no std :: copy_if algorithm?

Is there any specific reason for the lack of the std :: copy_if algorithm in C ++? I know that I can use std :: remove_copy_if to achieve the required behavior. I think it comes in C ++ 0x, but a simple copy_if instance that takes a range, an output iterator, and a functor would be nice. Was it just missing or is there some other reason?

+62
c ++ algorithm stl
Sep 19 '09 at 15:53
source share
6 answers

According to Stroustrup's "C ++ Programming Language", it was just an interception.

(as a quote, the same question was answered in advanced mailing lists: copy_if )

+41
Sep 19 '09 at 16:06
source share

Straustrup says they forgot it. This is in C ++ 11.

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

+27
Sep 19 '09 at 16:09
source share

Just for completeness, if someone goes this way to their own question, it should be mentioned that now (post C ++ 11) there is a copy if . It behaves as expected (copies 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); }); 
+9
May 10 '14 at 9:35
source share

Several sources indicate that he was accidentally excluded from the STL.

However, I'm not sure if this is a fact or a self-reproducing myth. I would appreciate it if someone pointed out that the source is more believable than a link to a random post on the Internet.

+7
Sep 19 '09 at 16:02
source share

He is dead easy to write on his 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; } 
+7
Sep 19 '09 at 16:40
source share

Just for completeness, I will add that boost has boost::algorithm::copy_if for those of you who can't use the C ++ 11 version (like me) in boost/algorithm/cxx11/copy_if.hpp that 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 
+1
Sep 06 '16 at 9:58
source share



All Articles