$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [function] function wrapping with no exceptionsafetyguarantee
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2010-10-30 14:47:21
On Sat, Oct 30, 2010 at 1:55 PM, Emil Dotchevski
<emil_at_[hidden]> wrote:
> On Sat, Oct 30, 2010 at 9:43 AM, Daniel Walker
> <daniel.j.walker_at_[hidden]> wrote:
>> Yes, if you look at the code in the benchmark, you will see that it is
>> measuring the cost of a call to a non-empty boost::function. In
>> optimized object code, the call is 4% faster without the check, but
>> removing the check means that it is necessary to store a special,
>> internal static object per instantiation to hold an "empty" function
>> that must be available if boost::function becomes empty.
>
> Do you really need a placeholder for each different boost::function signature?
Yes. Internally, boost::function creates a static object for each
signature to hold the target function. To hold the "empty" target
function, it must create a second static object per signature: one for
actual targets, one for an empty target.
>
> Since all it does is throw an exception, it should be safe to use the
> same placeholder for all signatures: http://codepad.org/3GxiTHZA.
The issue is not whether we create a new _type_ for the placeholder
per signature, but whether we create a new static _object_. So,
adapting your example, the following makes your function look a little
more like boost::function.
template<class R, class T0, class T1>
struct function
{
typedef R (*target_type)(T0,T1);
target_type f;
function()
{
static target_type stored_f = (target_type)&placeholder;
f = stored_f;
}
R operator()(T0 a, T1 b) { f(a,b); }
};
You can see that
function<void, int, int> f;
function<void, double, double> g;
would create two static stored_f objects, one per instantiation,
regardless of the type of placeholder. Good question!
Daniel Walker