Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |
Once you become comfortable with the style of STL
algorithms, you can begin to create your own generic algorithms. Because these
will conform to the conventions of all the other algorithms in the STL, they re
easy to use for programmers who are familiar with the STL, and thus they become
a way to extend the STL vocabulary.
The easiest way to approach the problem is to go to the <algorithm>
header file, find something similar to what you need, and pattern your code
after that. (Virtually
all STL implementations provide the code for the templates directly in the
header files.)
If you take a close look at the list of algorithms in the
Standard C++ library, you might notice a glaring omission: there is no copy_if( )
algorithm. Although it s true that you can accomplish the same effect with remove_copy_if( ),
this is not quite as convenient because you have to invert the condition.
(Remember, remove_copy_if( ) only copies those elements that don t
match its predicate, in effect removing those that do.) You might be
tempted to write a function object adaptor that negates its predicate before
passing it to remove_copy_if( ), by including a statement something
like this:
// Assumes pred is the incoming condition
replace_copy_if(begin, end, not1(pred));
This seems reasonable, but when you remember that you want
to be able to use predicates that are pointers to raw functions, you see why
this won t work not1 expects an adaptable function object. The only
solution is to write a copy_if( ) algorithm from scratch. Since you
know from inspecting the other copy algorithms that conceptually you need
separate iterators for input and output, the following example will do the job:
//: C06:copy_if.h
// Create your own STL-style
algorithm.
#ifndef COPY_IF_H
#define COPY_IF_H
template<typename ForwardIter,
typename OutputIter, typename UnaryPred>
OutputIter copy_if(ForwardIter begin, ForwardIter end,
OutputIter dest, UnaryPred f) {
while(begin != end) {
if(f(*begin))
*dest++ = *begin;
++begin;
}
return dest;
}
#endif // COPY_IF_H ///:~
Notice that the increment of begin cannot be
integrated into the copy expression.
Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |