
"Doug Gregor" <doug.gregor@gmail.com> wrote in message news:AANLkTimkWbdBaTe_4+uF4fDLcdC0yUgQ-c7eOKs_dryK@mail.gmail.com...
On Wed, Oct 20, 2010 at 1:51 PM, Daniel Walker <daniel.j.walker@gmail.com> wrote:
There would need to be a different "empty" vtable each time boost::function is instantiated with a different call signature, so that the "empty" vtable can be used seamlessly by operator() for any call signature.
One per boost::function signature, yes.
Actually, vtables are statically allocated one per "boost::function<> signature + target function object type" combination. The consequence of this is that if you assign a target to a b.function that has the same type as the on-empty-handler target there is/will be no (static space) overhead... The more different types of targets you assign to a b.function the additional overhead of an on-empty-handler target (if any as explained above) becomes relatively smaller and smaller... Moreover, even the above is almost irrelevant considering that: - the cdecl calling convention enables you to have a single throw-on-empty target vtable per binary/for all boost::function<> instantiations - the static overhead of two pointers is truly insignificant compared to other (unnecessary) code-bloat overheads inherent to the current implementation (including the usually inlined if-empty-then-throw code)... For example, in my implementation the vtable has four pointers but, in comparison to the improvements in both code size and code speed that this change made possible, this overhead is hardly worth noting (in fact it can hardly be called real overhead if it enables the reduction of the overhead of boost::function<> as a whole)... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman