C++ ambiguous call in function overloading
<p>Just a curiosity (academic question :P), consider the following code:</p>

<pre><code>struct Y {};

class PassConstY {
public:
    PassConstY(const Y&amp; y) {}
};

class PassY {
public:
    PassY(Y&amp; y) {}
};

void z(PassConstY y) {}
void z(PassY y) {}

void h(const Y&amp; y) {}
void h(Y&amp; y) {}

Y y;
const Y cy;
h(cy); //OK
h(y); //OK
z(cy); //OK
z(y); //Ambiguity
</code></pre>

<p>Question: is it possible to write <code>PassY</code> and <code>PassConstY</code> s.t. </p>

<ol>
<li><code>z</code> and <code>h</code> obeys exactly the same overloading rules</li>
<li>if I remove the <code>z</code> and <code>h</code> definitions for the mutable <code>Y</code> the code still compiles (i.e. I can call <code>z</code> and <code>h</code> with the mutable version too).</li>
</ol>

<p>My guess is no, in the sense that I managed to have <code>PassConstY</code> constructable from a <code>const Y</code> only (and not a mutable <code>Y</code>), which removes the ambiguity, but then point 2 is doomed to failure.</p>

<hr>

<p>Clarifications:</p>

<p>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.</p>

<p>The following code must compile when only the "const" versions of z and h are defined:</p>

<pre><code>const Y y;
z(y); //Calls z(PassConstY y)
h(y); //Calls h(const Y&amp; y)

Y x;
z(x); //Calls z(PassConstY y)
h(x); //Calls h(const Y&amp; y)
</code></pre>

<p>The following code must compile when only the "mutable" versions of z and h are defined:</p>

<pre><code>Y x;
z(x); //Calls z(PassY y)
h(x); //Calls h(Y&amp; y)
</code></pre>

<p>And the following code must compile when both versions of h and z are defined:</p>

<pre><code>const Y y;
z(y); //Calls z(PassConstY y)
h(y); //Calls h(const Y&amp; y)

Y x;
z(x); //Calls z(PassY y)
h(x); //Calls h(Y&amp; y)
</code></pre>

<p>Sorry if the original question was not clear enough!</p>

<hr>

<p>Motivations (really another question of mine here on Stackoverflow):</p>

<p>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:</p>

<pre><code>struct X {};

void f(Ref&lt;X&gt; x) {} //Instead of void f(X&amp; x)
void f(Ref&lt;const X&gt; x) {} //Instead of void f(const X&amp; x)
</code></pre>

<p>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. </p>

<p>[For this part, C++0X is needed]</p>
