From: Geurt Vos (G.Vos_at_[hidden])
Date: 2001-04-10 10:13:27
> > > I also think it would be more
> > > appropriate to throw than to return Result(),
> > It really depends on what 'function' is used for. When it's used
> > as e.g. predicate to whatever algorithm, it should throw. When
> > it's used to hold callback functions for an event driven system,
> > particularly when the return type is 'void', it would make sense
> > to simply ignore the call. Then again, the first one might be a
> > stronger argument. I mean, the 'even manager' or whatever could
> > of course simply perform a check before calling the function.
> Actually, I'd be in favor of having operator() not do a check and add
> a method call() that does a check. This would be inline with operator
>  and at() for std::vector, giving the programmer the best of both
> worlds depending on their own needs.
I actually came to the same conclusion while writing it...
> However, I still think the
> checked version needs to throw.
It should be configurable at compile-time IMO.
> > > and can think of no
> > > valid reason to ever use validate=false.
> > >
> > Efficiency. If it's used as predicate, it's more efficient to
> > check ones before calling the algorithm, than check on every
> > call.
> That's why the approach I gave above would be a good idea. Changing
> this behavior based on a template parameter just doesn't make sense
> to me.
Hmm, yeah, I threw it out :)
> > It's a flexibility & extendibility vs. efficiency trade of. I could
> > create an implementation similar to how it's solved for any_function,
> > but I still feel it's close to a hack, and at least harder to
> > understand. From a user point of view it won't really harm type
> > safety, though, and of course, there are easy ways to make it as
> > type strict as my implementation is.
> Efficiency is *very* important here. It's probably the most
> important aspect of this concept. Also, I still contend that you're
> wrong about type safety issues here.
Um, you're saying it does lose type safety from a user point of view?
But seriously, I'm not sure. If it's stable, it's fine.
> > Another reason for choosing the virtual function approach is because
> > 99% of the time the overhead generated by it is negligible. I don't
> > think designing out this overhead will really have that much effect,
> > unless you're really pushing the limits. In that case, I recommend
> > using a faster CPU :), because it's highly doubtful that if it were
> > designed out you won't run into performance problems elsewhere...
> The overhead is in a lot more than just speed. I'd suggest you read
> the list archives on this subject paying particular attention to the
> libsigc++ discussions. It was found in real world applications that
> virtual methods cause serious overhead issues for this particular
'serious overhead' is quite relative IMO. I mean, if for instance
an application turns out to be several MBs larger and uses several
MBs more, it's not necessarily serious.
If speed is quite the same, it's usually fine with me, and I choose
the solution that suits me best. You're right, of course, that speed
isn't the only issue of concern, which is particularly true for
libraries such as boost...
> > One last thing: assigning a function will cause memory allocation.
> > copy construction/assignment doesn't, because reference counting
> > is used...
> You *really* need to read the list archives at this point. We went
> down the ref-counting road, and I was one of the biggest supporters
> of this initially. I was convinced by the discussion that this is a
> bad idea, and believe you will be too if you read the archives.
I don't think it will convince me (duh), because in my case
reference counting gave me more than just a reference. It also
simplified both the interface and the implementation. I'll
search the archives...
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk