Yes, boost::function
is type safe even though it uses void pointers and pointers to functions returning void and taking no arguments. Essentially, all type information is encoded in the functions that manage and invoke function pointers and function objects. Only these functions are instantiated with the exact type that is pointed to by the void pointer or pointer to void function. The reason that both are required is that one may cast between void pointers and object pointers safely or between different types of function pointers (provided you don't invoke a function pointer with the wrong type).
Void returns are permitted by the C++ standard, as in this code snippet:
void f(); void g() { return f(); }
One reason for not using void returns is that not all compilers support them. In fact, very few compilers seem to support this trivial feature. Additionally, boost::function
is more flexible because it does not use void returns. Consider the following code:
int do_something(int); boost::functionf; f = do_something;
This is a valid usage of boost::function
because void returns are not used. With void returns, we would attempting to compile ill-formed code similar to:
int f(); void g() { return f(); }
In essence, not using void returns allows boost::function
to swallow a return value. This is consistent with allowing the user to assign and invoke functions and function objects with parameters that don't exactly match.
In November and December of 2000, the issue of cloning vs. reference counting was debated at length and it was decided that cloning gave more predictable semantics. I won't rehash the discussion here, but if it cloning is incorrect for a particular application a reference-counting allocator could be used.
Member function assignments are not included directly in boost::function
because they do not conform to the syntax of function objects. Several libraries exist to wrap member functions in a function object and/or bind the first argument to the member function (the this
pointer). A few libraries are described in the Boost.Function documentation.