Functions and Function Objects |
Many STL containers and algorithms require specifying a function to perform their operation. A function that takes one parameter is called a unary function, whereas a function that takes two parameters is called a binary function. STL defines three categories of functions.
true or falsetrue or falseFunctions are supplied as either pointers to regular C functions or as function objects. STL function objects encapsulate and associate functions with data. Using STL function objects, functions can be created, stored, and destroyed just like any other object.
Every function object supplies an
operator() , so it can be executed using the
regular function call syntax. In addition, most
function objects are templates for type safety.
STL contains over 30 function
objects. The following example uses a less function
object to order an STL set
.
#include <iostream>
#include <set>
void
main()
{
set< int, less< int > > s;
s.insert( 1 );
s.insert( 42 );
s.insert( 3 );
set< int, less< int > >::iterator p;
for ( p = s.begin(); p != s.end(); ++p ) // Display contents.
cout << *p << "\n";
}
1
3
42
Predicates trigger actions and
always return true or false
. A unary predicate takes a single argument. A
binary predicate takes two arguments. For example, the count_if()
algorithm counts all of the values in a sequence satisfying a user-supplied
unary predicate. The following example passes the address of the regular C
function bigger() to count_if()
, which in turn uses bigger() to
count the numbers in a sequence that are greater than three.
#include <iostream>
#include <algorithm>
#include <vector>
bool
bigger( int i )
{
return i > 3;
}
void
main()
{
vector< int > v;
v.push_back( 4 );
v.push_back( 1 );
v.push_back( 5 );
int n = 0;
count_if( v.begin(), v.end(), bigger, n );
cout << "Number greater than 3 = " << n << "\n";
}
number greater than 3 = 2
STL includes a unary function
object called logical_not() that returns true
if its single operand is false . The following
example uses logical_not() to
count all the false elements in an array.
#include <iostream>
#include <algorithm>
#include <functional>
bool input[ 7 ] = { 1, 0, 0, 1, 1, 1, 1 };
void
main()
{
int n = 0;
count_if( input, input + 7, logical_not< bool >(), n );
cout << "count = " << n << "\n";
}
count = 2
Following is a list of algorithms that accept unary predicates.
Following is a list of algorithms that accept binary predicates.
Comparators are binary
functions that order elements and always return true
or false . When a comparator returns true
, it generally means the first parameter is ordered before the second
parameter. For example, with one variation of sort()
you can specify a function that controls the
sorting order.
In the following example, bigger_than()
tells sort() to place x
to the left of y if x
is greater than y .
#include <iostream>
#include <algorithm>
#include <vector>
bool
bigger_than( int x, int y )
{
return x > y;
}
void
main()
{
vector< int > v;
v.push_back( 4 );
v.push_back( 1 );
v.push_back( 5 );
sort( v.begin(), v.end(), bigger_than );
vector< int >::iterator i;
for ( i = v.begin(); i != v.end(); ++i )
cout << *i << "\n";
}
5
4
1
The following example uses a greater
function object to sort a collection of items in
descending order.
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
void
main()
{
vector< int > v;
v.push_back( 4 );
v.push_back( 1 );
v.push_back( 5 );
sort( v.begin(), v.end(), greater< int >() );
vector< int >::iterator i;
for ( i = v.begin(); i != v.end(); ++i )
cout << *i << "\n";
}
5
4
1
The previous example uses
inline construction of a greater function
object for convenience. The following code achieves the same effect.
greater< int > g; // Construct a greater function object.
sort( v.begin(), v.end(), g ); // Call with function object.
Following is a list of algorithms that accept a comparator.
STL containers often contain pointers to objects or strings. STL does not contain function objects for comparing these two kinds of items properly, so Helper<ToolKit> includes a variety of non-standard comparators and functions for solving this problem. Consult the Foundations User Guide and Reference Manual for more information about Helper<ToolKit>.
Many algorithms use a general
function to apply a mathematical operation to every element in a collection.
For example, the transform()
algorithm applies a unary function to every item in a collection and stores
the result into another collection.
The following example uses a negate
object to negate every element in a collection.
#include <iostream>
#include <algorithm>
#include <functional>
int array[] = { 1, 5, 2, 3 };
int result[ 4 ];
void
main()
{
transform( array, array + 4, result, negate< int >() );
for ( int i = 0; i < 4; ++i )
cout << result[ i ] << " ";
cout << "\n";
}
-1 -5 -2 -3
The transform()
algorithm is the only algorithm that uses a unary
operation. Following is a list of algorithms that use a binary operation.
Several function objects have an associated adapter function that simplifies the syntax of creating instances.
The following example collects
even numbers from a container using a function object that tests whether a
number is odd. Notice that the function object unary_negate
takes a unary predicate and returns the
complement. A unary predicate is a function that takes one argument. In this
case, the unary_negate turns odd(x)
into !odd(x) .
#include <iostream>
#include <algorithm>
#include <functional>
int array[ 3 ] = { 1, 2, 3 };
class odd : public unary_function< int, bool >
{
public:
odd() {}
bool operator()( const int& n ) const { return ( n % 2 ) == 1; }
};
void
main()
{
int* p = find_if( array, array + 3, unary_negate< odd >( odd() ) );
if ( p != array + 3 )
cout << *p << "\n";
}
2
For convenience, unary_negate
has an adapter function called not1()
that does the work of instantiating unary_negate
. Using not1 , you can write the same example
in the following way.
#include <iostream>
#include <algorithm>
#include <functional>
int array[ 3 ] = { 1, 2, 3 };
class odd : public unary_function< int, bool >
{
public:
odd() {}
bool operator()( const int& n ) const { return ( n % 2 ) == 1; }
};
void
main()
{
int* p = find_if( array, array + 3, not1( odd() ) );
if ( p != array + 3 )
cout << *p << "\n";
}
2
If a function object has an adapter, it is described in that function object's entry in the class catalog found in the second half of this manual.
Following is a complete list of all the standard STL function objects, with the argument count and synopsis of operation for each.
| Function | # args | Operation | Adapter |
|---|---|---|---|
Copyright©1994-2026 Recursion
Software LLC
All Rights Reserved - For use by licensed users only.