
Joel de Guzman wrote:
Dean Michael Berris wrote:
So the only alternative really (or at least the one I see that doesn't run into the forwarding problem) is the linear inheritance approach I've been mentioning. Now getting towards implementing that approach is another discussion and effort in itself -- one I'm still mulling around if it's even worth pursuing, given the cases I intend to cover with the dispatcher. If at all possible, even an enhancement to Boost.Function might be handy which will allow it to contain function pointers to multiple signatures -- but I'm not that ambitious (yet) to try and hack at Boost.Function to enable multiple signature support and compile-time dispatching based on argument type lookup.
I think I've mentioned that I have such a "overloads" library extension in my HD somewhere. At one point, I asked Doug on the possibility of adding it to boost.function and he expressed his interest. Of course that means documentation and stuff. I'll try to see if I can squeeze some time to get this into completion. At any rate, I can post the code sans docs.
[CC'ing Doug] Ok, here's the proof of concept: http://spirit.sourceforge.net/dl_more/overload/ Here's the original text I sent Doug: Boost.function is a very useful library for wrapping function objects. Yet, one limitation it has, compared to generic function objects, is that it is monomorphic. It has a specific fixed signature and is unusable polymorphically. One particular case it can't be used for, for example, is as a visitor for boost variant. But that view is minimalistic. I don't think I need to expound on the virtues of overloaded functions. But, let me show some examples anyway... Say we have a boost.function named "concat". It can be called much like any function. For example: concat(str, str2) Boost.function has a fixed signature. For example, "concat" can be declared as: function<std::string(std::string, std:string)> Now here lies the problem... But, I'd like to also allow: concat(str, 'x') concat(str, "Hi") concat("Hi", str) concat('x', str) or possibly even: concat("Hi", ", World") concat('x', 'y') Unfortunately, we can't use boost.function like that because it is monomorphic. (Sure, "Hi" can be implicitly converted to a std::string, but a temporary will have to be created. We are out of luck for 'x': there is no implicit conversion). Hence, I'd like to propose an extension (or a separate library) for allowing overloads for boost.function. The example above can be declared as: boost::overload< std::string(std::string, std:string) , std::string(std::string, char) , std::string(std::string, char const*) , std::string(char, std::string) , std::string(char const*, std::string) > concat; Since "concat" is polymorphic, its declaration can be extended to also support wide strings. Sure, you can have different return types! Also, we are not limited to 2 argument overloads. We can also allow: concat(str, cstr, len) [...end concat example...] Now, for Spirit, what I wanted to do, for a long time now, is reduce the Spirit "rule" to a boost.function. Yet, as of Spirit 1.8, I found that it is not possible to use boost.function as-is because its "rule" can be parameterized to take in a couple of scanner types (e.g. one with space-skipping, one without): r.parse(plain-scanner); r.parse(skip-scanner); With the proposed overload extension, I can now do that. Here's Doug's reply: Very cool. This is one of those "... you don't need it often, but when you need it you *really* need it" features. If you're interested in finished it up, I'd be happy to put it straight into the Function library. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net