
"Mathias Gaunard" <mathias.gaunard@ens-lyon.org> wrote in message news:ha52jl$4oc$1@ger.gmane.org...
Domagoj Saric wrote:
As far as I can see boost::function<>::operator() performs: if (this->empty()) boost::throw_exception(bad_function_call()); before invoking the stored function (object)... My question is why or why only this "checked"/"safe" approach/method of invocation exists?
BOOST_ASSERT(!empty()) would be better in my opinion indeed, but it's hard to make that change now for compatibility reasons.
considering the improvement is more than cosmetic i'm (always) for breaking changes (but then again i do not, yet, 'live' in the 'conservative corporate universe' where you bow to BackwardCompatibility ;)... but, come to think of it, there is an (almost) win win solution... what if the check-and-throw is not performed with an explicit if-and-throw but rather a default constructed or emptied boost::function<> object does not actually become 'empty' (in the sense that it holds a null pointer/object) but rather it holds a default/static/shared function pointer/object that does the actual throw... ...this is an 'almost' win win solution because you now get a thin/inlined away function<>::operator() and the same 'safe' behaviour but are still left with exceptions (the compiler still must 'regard' operator() as a possibly throwing function)... if we go further we could add one more useful behaviour without breaking changes...the default behaviour could be parameterized (with the default being the exception throw for backward compatibility) to be: 1. throw 2. assert in debug - access violate on a null pointer in release 3. nop the third option would eliminate the tipical: { if ( myFunction ) myFunction(); } code (it would, in fact/actually eliminate the branching from the generate code itself, because it would be implemented by calling a function through a pointer, that you would do anyway, that does nothing, simply returns)... now, if we make the parameter for the OnEmpty behaviour a template parameter we could have a truly win-win solution (if ofcourse, one could implicitly add the __declspec( nothrow ) or equivalent function declaration 'decorator' to the boost::function<>::operator() based on a template parameter and/or actual used function object type)... seeing this article http://www.codeproject.com/KB/cpp/fastdelegate2.aspx makes me realize (or just think?) that the same approach can be used to create multicast functions/delegates (didn't yet have time to check how was it implemented in that article/if there is a better solution) without 'breaking changes', or creating a new boost::multicast_function<> class or adding any runtime overhead to boost::function<> instances that would not use multicasting capabilities (multicasting would/could be implemented by a special internal function object that calls the many stored functions in a list, or thru a function chain of some sort...) -- "That men do not learn very much from the lessons of history is the most important of all the lessons of history." Aldous Huxley