
On Sat, 13 Oct 2007 08:20:32 +0200, Marco Costalba <mcostalba@gmail.com> wrote:
On 10/12/07, Marco <mrcekets@gmail.com> wrote:
- if the intersection between "rs" and "ss" is not empty then the new target (i.e. "f") overwrites all the targets related to the signatures included in the intersection.
I hope to have answered to your question.
Yes thanks. I would have read the previous posted policy better.
My concern has more to do with a language corner than with overload 'per se'.
The whole point is that the 'comparison' used when adding a function to the overload set is different from the 'comparison' used when choosing among the function given a set of arguments, i.e. at call time.
In particular at registering time we (but also C++ compiler) uses perfect signature match to test a function signature against the others.
As example
class A { void foo(char); void foo(long); };
compiles because void(char) and void(long) are different function types. Also
void foo1(char); void foo2(long);
boost::overload<void(char), void(long)> ov;
ov.set(&foo1); ov.set(&foo2);
compiles the same.
But at call time matching between passed in arguments and function to call is done (in C++) not with "perfect type match" comparison but with "type match + implicit conversions" comparison.
That's the reason that instruction;
A a; a.foo(7); // compile error!
fails with message "ambiguous call, 2 candidates...", not with message 'I don't find a suitable foo()'
This ambiguity is, of course, intrinsically present also in 'overload' because registering is done on perfect signature matching, while at runtime class member overloading is used (i.e. implicit conversions are taken in account).
Please note that this is good! is what C++ does, the only difference is that with
a.foo(7);
a compile error is produced and user is warned about this ambiguity that he must resolve explicitly in some way.
I didn't know what, in the above case
ov(7);
should produce.
You catched exactly the point. :-) At call time boost::overload rules are the same followed by normal (member) function calls. There is no surprise for the user. What's better ? I want only to point out that there is nothing odd in the fact that C++ allows to define both:
void foo(char); void foo(long); because the compiler doesn't know if the call will be ambiguos or not, that is:
foo(7); // is ambiguos, but long l = 7; foo(l); // there is no ambiguity Problably you had already argued all that, but just to be sure :-)
Thanks Marco
You're welcome, good weekend, Marco
P.S: In case you are wondering "why didn't he tried?" is that I had some compiler error (probably SFINAE related) and didn't had the time to dig it more.
That sounds odd to me I used only partial template specialization and just one enable_if in all my code. What compiler are you using ? -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/