Just a curiosity (academic question :P), consider the following code:
struct Y {}; class PassConstY { public: PassConstY(const Y& y) {} }; class PassY { public: PassY(Y& y) {} }; void z(PassConstY y) {} void z(PassY y) {} void h(const Y& y) {} void h(Y& y) {} Y y; const Y cy; h(cy); //OK h(y); //OK z(cy); //OK z(y); //Ambiguity Question: is it possible to write PassY and PassConstY s.t.
zandhobeys exactly the same overloading rules- if I remove the
zandhdefinitions for the mutableYthe code still compiles (i.e. I can callzandhwith the mutable version too).
My guess is no, in the sense that I managed to have PassConstY constructable from a const Y only (and not a mutable Y), which removes the ambiguity, but then point 2 is doomed to failure.
Clarifications:
PassY and PassConstY can be defined as you prefer (but must be classes, may be templated) but the definitions of z and h must be unchanged.
The following code must compile when only the "const" versions of z and h are defined:
const Y y; z(y); //Calls z(PassConstY y) h(y); //Calls h(const Y& y) Y x; z(x); //Calls z(PassConstY y) h(x); //Calls h(const Y& y) The following code must compile when only the "mutable" versions of z and h are defined:
Y x; z(x); //Calls z(PassY y) h(x); //Calls h(Y& y) And the following code must compile when both versions of h and z are defined:
const Y y; z(y); //Calls z(PassConstY y) h(y); //Calls h(const Y& y) Y x; z(x); //Calls z(PassY y) h(x); //Calls h(Y& y) Sorry if the original question was not clear enough!
Motivations (really another question of mine here on Stackoverflow):
Regaring the "disable r-value binding" in the comment below, I would like to come up with a template class Ref (think of it like a smart reference) that I can use when I write function definitions like:
struct X {}; void f(Ref<X> x) {} //Instead of void f(X& x) void f(Ref<const X> x) {} //Instead of void f(const X& x) so that I get the same behaviour when calling the function f (in terms of overloading resolution/conversions) as for the plain reference versions, but Ref never binds to rvalues.
[For this part, C++0X is needed]