Boost logo

Boost :

From: Karl Nelson (kenelson_at_[hidden])
Date: 2000-11-20 03:12:59


[error generation]
> >
> > SigC spits out
> >
> > on line
> > s=slot(&mul_to_int);
> >
> > test.cc:8: no match for `SigC::Slot2<int,float,float> & = SigC::Slot3<int,f
> loat,float,bool>'
> > /usr/local/include/sigc++/slot.h:489: candidates are: class SigC::Slot2<int
> ,float,float> & SigC::Slot2<int,float,float>::operator =(const SigC::Slot2<in
> t,float,float> &)
> >
> > Likely this last one isn't an issue to you. But to my users it
> > really is important.
>
> I consider it an issue, but I know it is also solvable. I've just uploaded an
> updated version of a callback library which emits more readable error messag
> es, e.g., the following code
>
>
> struct hello_world {
> int operator() { return 5; }
> };
> // ...
> callback<void> cb1;
> cb1 = hello_world();
>
> Will return this error message with g++-2.95.2:
>
> callback1.cpp:22: instantiated from here
> ../../boost/callback.hpp:236: `function_call_operator_signatures_are_not_comp
> atible_with_callback' is not a member of type `boost::INVALID_CALLBACK_TARGET
> <hello_world>'

Better, though not quite
   'no match for callback<void,int> = callback<void,int,int>'

> More metaprogramming could yield more accurate error messages, but VC++ has b
> ecome the limiting factor.

VC++ is always a limiting factor. I had to jump through a hell
of a lot of huddles to get my code to work there and some of the
template formulations still cause random errors. I hope that
someday everyone here comes to realize how worthless that
sorry excuse for a compiler is and boycots it.

Speaking of lame compilers, not all compilers have void returns.
For those without it like VC++ you can use the int return trait trick.
However, on others like SGI compiler this may fail. For SGI you would
need to specialize callback<void,...> and all the implementations
using partial specialization.
(This is one of the things the really confused people in SigC, there
are multiple formulations there to cover the bad case compilers. It
makes for reams of code which just gets skipped on most compilers.)

So lets look at another minor issue. That is the virtuals tables.
I benchmarked your callbacks against SigC 1.1 slots for binary size.
I implemented 21 functors like this

struct func_float_int_int
{
  float operator()(int a, int b) { return float(a*b); }
};

for combinations of float, int, and double. In then made one
callback for each functor, set it and called it. The
resulting binary was 430k debug and 30K striped. Most of the space was
nothing but almost wothless typeinfo functions.

 00000094 W boost::detail::functor_callback<func_int_int_int, int, int, int, boost::detail::Unused> type_info function

SigC 1.1 formulation on similar test was 90k debug and 17.4k striped.
(done with static linking though much of is sharable in a library)
This difference came because SigC didn't use the virtual table to launch the
callback but instead a function pointer. However, I don't believe
a similar technique is possible in your code.

This raise the problem I expressed before, that if you use a large
number of functor types it can eat a lot in binary size. It doesn't
look to extreme for your library, but you should test with
reasonable numbers of callbacks and functors to see how much it scales.
I only optomized SigC because gtk-- used several hundred which
would have added 2M to the library binary size in typeinfo and
similar stuff.

Hope it helps.

--Karl


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