The std::function
class template lacks the user-specified allocator support available in its predecessor
boost::function
. The current definition of boost::function
provides a second template parameter that
can be utilized to pass a custom allocator class to be used when memory allocations are needed. This second template
parameter is optional and defaults to std::allocator
.
The main drawback of the allocator support in boost::function
is that using a different allocator type
leads to different instances of the boost::function
class template, even for functions that have the
same signature.
This document proposes an alternative approach for custom allocator support for std::function
without
adding a second template parameter.
The following are the types of function objects that can be used to initialize a std::function
object:
It is possible for std::function
implementations to avoid dynamic allocations in the first two cases.
In general, dynamic allocations can not be avoided in the third case. The current behavior of std::function
in this case is to use new
. This precludes its use in contexts where uncontrolled dynamic allocations
are not allowed, such as embedded environments.
Note that any use of std::bind
with std::function
, even when the targeted object is either
pointer to function or pointer to member function, leads to the third case and the potential need for dynamic allocations.
The proposed custom allocator support is consistent with the proposed allocator support in shared_ptr
(N2232).
Both shared_ptr
and std::function
instances retain source and binary compatibility
independently of whether user-defined allocator was used or not.
The allocator support does not add a second parameter to the std::function
class template.
It has no overhead when no allocator is used.
Even when a custom allocator is supplied, the resulting std::function
object is indistinguishable from
any other instance of the std::function
class template that use the same signature.
The proposed feature affects the interface of std::function
, allowing its broader use, and is therefore
strongly recommended to be added to the C++0x standard.
Add to std::function
the following constructor:
template <class F,class A> function( F f, A a );
Requires: f
shall be callable for argument types ArgTypes
and
return type R
. A
shall be an allocator [allocator.requirements]. The copy constructor and destructor
of A
shall not throw.
Postconditions: !*this
if any of the following hold:
f
is a NULL
function pointer.f
is a NULL
member function pointer.F
is an instance of the function class template, and !f
Otherwise, *this
targets a copy of f
or move(f)
if f
is not a pointer
to member function, and targets a copy of mem_fn(f)
if f
is a pointer to member function. A copy
of a
shall be used if dynamic storage must be allocated for the copy of f
. [Note:
Implementations are encouraged to avoid the use of dynamically allocated memory for small function objects, e.g., where
f
’s target is an object holding only a pointer or reference to an object and a member function pointer --
end note.]
Throws: shall not throw exceptions when f
is a function pointer or a reference_wrapper<T>
for some T
. Otherwise, may throw bad_alloc
or any exception thrown by F
’s copy or
move constructor.
Add to std::function
the following member function template:
template <class F,class A> void assign( F f, A a );
Effects: function(f,a).swap(*this);
A proof of concept implementation is available at:
http://www.revergestudios.com/boost-function
It is expected to be integrated with boost::function
in time for the mailing.
Thanks to Peter Dimov and Doug Gregor for reviewing this document.
--end