Boost logo

Boost :

From: Joel de Guzman (joel_at_[hidden])
Date: 2007-09-30 20:25:04

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:

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:

         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)

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):


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


Joel de Guzman

Boost list run by bdawes at, gregod at, cpdaniel at, john at