Header <boost/function.hpp>

The header <boost/function.hpp> includes a family of class templates that are function object wrappers. The notion is similar to a generalized callback. It shares features with function pointers in that both define a call interface (e.g., a function taking two integer arguments and returning a floating-point value) through which some implementation can be called, and the implementation that is invoked may change throughout the course of the program.

Generally, any place in which a function pointer would be used to defer a call or make a callback, Boost.Function can be used instead to allow the user greater flexibility in the implementation of the target. Targets can be any 'compatible' function object (or function pointer), meaning that the arguments to the interface designated by Boost.Function can be converted to the arguments of the target function object.

Boost.Function vs. Function Pointers

Boost.Function has several advantages over function pointers, namely:

And, of course, function pointers have several advantages over Boost.Function:

The above two lists were adapted from comments made by Darin Adler.

Performance

Function object wrapper size

Function object wrappers will be the size of two function pointers plus one function pointer or data pointer (whichever is larger). On common 32-bit platforms, this amounts to 12 bytes per wrapper. Additionally, the function object target will be allocated on the heap.

Copying efficiency

Copying function object wrappers requires allocating member for a copy of the function object target. The default allocator may be replaced with a faster custom allocator if the cost of this cloning becomes prohibitive.

Invocation efficiency

With a properly inlining compiler, an invocation of a function object requires one call through a function pointer. If the call is to a free function pointer, an additional call must be made to that function pointer (unless the compiler has very powerful interprocedural analysis).

Portability

The function object wrappers have been designed to be as portable as possible, and to support many compilers even when they do not support the C++ standard well. The following compilers have passed all of the testcases included with boost::function.

The following compilers work with boost::function, but have some problems:

If your compiler is not listed, there is a small set of tests to stress the capabilities of the boost::function library. A standards-compliant compiler should compile the code without any modifications, but if you find you run into problems please submit a bug report.

Design rationale

Combatting virtual function bloat

The use of virtual functions tends to cause 'code bloat' on many compilers. When a class contains a virtual function, it is necessary to emit an additional function that classifies the type of the object. It has been our experience that these auxiliary functions increase the size of the executable significantly when many boost::function objects are used.

In Boost.Function, an alternative but equivalent approach was taken using free functions instead of virtual functions. The Boost.Function object essentially holds two pointers to make a valid target call: a void pointer to the function object it contains and a void pointer to an "invoker" that can call the function object, given the function pointer. This invoker function performs the argument and return value conversions Boost.Function provides. A third pointer points to a free function called the "manager", which handles the cloning and destruction of function objects. The scheme is typesafe because the only functions that actually handle the function object, the invoker and the manager, are instantiated given the type of the function object, so they can safely cast the incoming void pointer (the function object pointer) to the appropriate type.

A compiler with strong interprocedural analysis could significantly reduce the overhead associated with virtual function calls such that the alternative used by Boost.Function is less efficient. No compiler has yet been found where this is true, but when it does occur the BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS macro can be defined to revert to the simpler implementation based on virtual functions.

Acknowledgements

Many people were involved in the construction of this library. William Kempf, Jesse Jones and Karl Nelson were all extremely helpful in isolating an interface and scope for the library. John Maddock managed the formal review, and many reviewers gave excellent comments on interface, implementation, and documentation.


Doug Gregor