4.4.3 Function Adaptors

Negators. The negators not1 and not2 are functions which take a unary and a binary predicate, respectively, and return their complements.


template <class Predicate>
unary_negate<Predicate> not1(const Predicate& pred) {
   return unary_negate<Predicate>(pred);
}

template <class Predicate>
binary_negate<Predicate> not2(const Predicate& pred) {
   return binary_negate<Predicate>(pred);
}

The classes unary_negate and binary_negate only work with function object classes which have argument types and result type defined. That means, that Predicate::argument_type and Predicate::result_type for unary function objects and Predicate::first_argument_type, Predicate::second_argument_type and Predicate::result_type for binary function objects must be accessible to instantiate the negator classes.


vector<int> v;
// fill v with 1 2 3 4

sort (v.begin(), v.end(), not2 (less_equal<int>()) );

Output: 4 3 2 1


Binders. "The binders bind1st and bind2nd take a function object f of two arguments and a value x and return a function object of one argument constructed out of f with the first or second argument correspondingly bound to x.", [2],11.3.2. Imagine that there is a container and you want to replace all elements less than a certain bound with this bound.
vector<int> v;
// fill v with 4 6 10 3 13 2

int bound = 5;

replace_if (v.begin(), v.end(), bind2nd (less<int>(), bound), bound);

// v: 5 6 10 5 13 5

bind2nd returns a unary function object less that takes only one argument, because the second argument has previously been bound to the value bound. When the function object is applied to a dereferenced iterator i, the comparison *i < bound is done by the function-call operator of less.

Adaptors for pointers to functions. The STL algorithms and adaptors are designed to take function objects as arguments. If a usual C++ function shall be used, it has to be wrapped in a function object.

The function ptr_fun takes a unary or a binary function and returns the corresponding function object. The function-call operator of these function objects simply calls the function with the arguments provided.

For example, if a vector of character pointers is to be sorted lexicographically with respect to the character arrays pointed to, the binary C++ function strcmp can be transformed into a comparison object and can so be used for sorting.


vector<char*> v;
char* c1 = new char[20]; strcpy (c1, "Tim");
char* c2 = new char[20]; strcpy (c2, "Charles");
char* c3 = new char[20]; strcpy (c3, "Aaron");
v.push_back (c1); v.push_back (c2); v.push_back (c3);

sort (v.begin(), v.end(), ptr_fun (strcmp) );
copy (v.begin(), v.end(), ostream_iterator<char*> (cout, " ") );

Output: Aaron Charles Tim


Note: The above example causes memory leaks, because the memory allocated with new is not automatically deallocated. See section 4.5 for a solution.

Continue with section 4.5

Back to index


Johannes Weidl (J.Weidl@infosys.tuwien.ac.at) - Apr 16, 1996