On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

### Predicates

At times, you might want to copy only a well-defined subset of one sequence to another, such as only those elements that satisfy a particular condition. To achieve this flexibility, many algorithms have alternate calling sequences that allow you to supply a predicate, which is simply a function that returns a Boolean value based on some criterion. Suppose, for example, that you only want to extract from a sequence of integers those numbers that are less than or equal to 15. A version of copy( ) called remove_copy_if( ) can do the job, like this:

//: C06:CopyInts2.cpp
// Ignores ints that satisfy a predicate.
#include <algorithm>
#include <cstddef>
#include <iostream>
using namespace std;

// You supply this predicate
bool gt15(int x) { return 15 < x; }

int main() {
int a[] = { 10, 20, 30 };
const size_t SIZE = sizeof a / sizeof a[0];
int b[SIZE];
int* endb = remove_copy_if(a, a+SIZE, b, gt15);
int* beginb = b;
while(beginb != endb)
cout << *beginb++ << endl; // Prints 10 only
} ///:~

The remove_copy_if( ) function template takes the usual range-delimiting pointers, followed by a predicate of your choosing. The predicate must be a pointer to a function[86] that takes a single argument of the same type as the elements in the sequence, and it must return a bool. Here, the function gt15 returns true if its argument is greater than 15. The remove_copy_if( ) algorithm applies gt15( ) to each element in the input sequence and ignores those elements where the predicate yields true when writing to the output sequence.

The following program illustrates yet another variation of the copy algorithm:

//: C06:CopyStrings2.cpp
// Replaces strings that satisfy a predicate.
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <string>
using namespace std;

// The predicate
bool contains_e(const string& s) {
return s.find('e') != string::npos;
}

int main() {
string a[] = {"read", "my", "lips"};
const size_t SIZE = sizeof a / sizeof a[0];
string b[SIZE];
string* endb = replace_copy_if(a, a + SIZE, b,
contains_e, string("kiss"));
string* beginb = b;
while(beginb != endb)
cout << *beginb++ << endl;
} ///:~

Instead of just ignoring elements that don t satisfy the predicate, replace_copy_if( ) substitutes a fixed value for such elements when populating the output sequence. The output is:

kiss
my
lips

because the original occurrence of read, the only input string containing the letter e, is replaced by the word kiss, as specified in the last argument in the call to replace_copy_if( ).

The replace_if( ) algorithm changes the original sequence in place, instead of writing to a separate output sequence, as the following program shows:

//: C06:ReplaceStrings.cpp
// Replaces strings in-place.
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <string>
using namespace std;

bool contains_e(const string& s) {
return s.find('e') != string::npos;
}

int main() {
string a[] = {"read", "my", "lips"};
const size_t SIZE = sizeof a / sizeof a[0];
replace_if(a, a + SIZE, contains_e, string("kiss"));
string* p = a;
while(p != a + SIZE)
cout << *p++ << endl;
} ///:~

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

 Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire