Previous fileTop of DocumentContentsIndex pageNext file
Apache C++ Standard Library User's Guide

3.2 Function Objects

3.2.1 Definition

A function object is an object to which the function call operator can be applied. Typically, it is a class that defines the function call operator (operator()()) as a member function. When a function object is used as a function, the function call operator is invoked whenever the function is called. Consider the following class definition:

If we create an instance of class biggerThanThree, every time we reference this object using the function call syntax, the function call operator member function is invoked. To generalize this class, we add a constructor and a constant data member, which is set by the constructor:

The result is a general biggerthanX function, where the value of X is determined when we create an instance of the class. We can do so, for example, as an argument to one of the generic functions that require a predicate. In this manner the following code finds the first value in a list that is larger than 12:

3.2.2 Use

There are a number of situations where it is convenient to substitute function objects in place of functions: to use an existing function object provided by the C++ Standard Library instead of a new function; to improve execution by using inline function calls; and to allow a function object to access or set state information that is held by an object. Let's deal with each of these in the next three sections.

3.2.2.1 To Employ Existing C++ Standard Library Function Objects

Table 5 illustrates the function objects provided by the C++ Standard Library.

Table 5: Function objects provided by the C++ Standard Library 

Function object Implemented operations

Arithmetic functions

plus

addition x + y

minus

subtraction x - y

multiplies

multiplication x * y

divides

division x / y

modulus

remainder x % y

negate

negation - x

Comparison functions

equal_to

equality test x == y

not_equal_to

inequality test x != y

greater

greater-than comparison x > y

less

less-than comparison x < y

greater_equal

greater than or equal comparison x >= y

less_equal

less than or equal comparison x <= y

Logical functions

logical_and

logical conjunction x && y

logical_or

logical disjunction x || y

logical_not

logical negation ! x

Let's look at a couple of examples that show how these might be used. The first example uses std::plus<int>() to compute the by-element addition of two lists of integer values, placing the result back into the first list. This can be performed by the following code:

The second example negates every element in a vector of boolean values:

The base class templates used by the C++ Standard Library to define the functions in Table 5 are also available for creating new unary and binary function objects. The class templates unary_function and binary_function are defined in the header <functional>.

The base classes are defined as follows:

An example of the use of these templates is found in Section 6.3. There we want to take a binary function of type Widget and an argument of type int, and compare the widget identification number against the integer value. A function to do this is written in the following manner:

The importance of inheritance from one of the two base class templates becomes apparent when elementary function objects are composed to form complex expressions using negators and binders, which are explained in Section 3.5.

3.2.2.2 To Improve Execution

A second reason to consider using function objects instead of functions is faster code. The difference between a function and an object of a class that defines the member operator()() is that functions are converted to pointers when passed as arguments to other functions, thus incurring the overhead of a function call even if they are declared inline. In many cases an invocation of a function object, as in the examples on std::transform() in Section 3.2.2.1, can be expanded in-line, eliminating the overhead of a function call.

3.2.2.3 To Access or Set State Information

The third major reason to use a function object in place of a function is when each invocation of the function must remember some state set by earlier invocations. An example of this occurs in the creation of a generator, to be used with the generic algorithm std::generate(). A generator is simply a function object that takes no arguments and returns a new (and possibly different) value each time it is invoked. The most commonly used form of generator is a random number generator, but there are other uses for the concept. A sequence generator simply returns the values of an increasing sequence of natural numbers (1, 2, 3, 4 and so on). We can call this object iotaGen after the similar operation in the programming language APL, and define it as follows:

An iota object maintains a current value, which can be set by the constructor, or defaults to zero. Each time the function-call operator is invoked, the current value is returned, and also incremented. Using this object, the following call on the C++ Standard Library function std::generate() initializes a vector of 20 elements with the values 1 through 20:

A more complex example of using a function object occurs in the radix sorting example program, which is given as an example of using the list datatype in Section 6.3. In this program references are initialized in the function object, so that during the sequence of invocations the function object can access and modify local values in the calling program.



Previous fileTop of DocumentContentsIndex pageNext file