Boost logo

Boost :

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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk