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?
+5
A:
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.
Alex B
2009-09-19 16:02:18
Here's a non-random post on the internet, selected on the basis that it claims to be an email from Stroustrup to the Boost mailing list: http://lists.boost.org/Archives/boost/2001/01/8030.php. Of course it could be a fraud, or it could be that Stroustrup himself has bought the myth. I guess it's possible that Stepanov generally thought it best to have `remove_copy_if`, and deliberately excluded `copy_if` as redundant. But seriously, it's clearly some kind of mistake to have `remove_copy_if` but not `copy_if`, if only one of taste :-)
Steve Jessop
2010-04-17 02:45:36
+4
A:
Stroustrup says they forgot it.
However, you can use remove_copy_if
(which really should be called copy_if_not
) along with not1
instead.
rlbond
2009-09-19 16:09:25
+4
A:
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;
}
alex tingle
2009-09-19 16:40:37
This isn't actually correct, as noted in *Effective STL* item 36, because it only works on adaptable functors.
rlbond
2009-09-19 18:00:33
looks like it's not that dead easy, it seems that your second attempt returns the first value matching the predicate - besides, IMHO, you're a little off-topic here
rotoglup
2009-09-26 10:08:30
rotoglup - I'm afraid that you don't know what you're talking about. 'result' is an OutputIterator. I did test this code you know.
alex tingle
2009-09-26 10:14:43
Don't you have to iterate the OutputIterator? `*(result++) = *first;`
Peter Kovacs
2010-01-26 02:03:34
@Peter Kovacs - nope. I thought that too at first, but if you check you'll find that you don't need to explicitly increment it.
alex tingle
2010-01-27 15:43:02
I think that might just be a side-effect of the way the stl output iterators work. For example this code fails to compile with your copy_if: `int A[] = { 1, 2, 3, 4, 5, 6 }, B[ 3 ];` `copy_if( A, A + sizeof( A ) / sizeof( A[ 0 ] ), B, `However, it works if you use `*result++ = *first;`
Peter Kovacs
2010-01-29 14:16:23