Function Matching for parameters of type const T& and T
c++, c++11
Solution
One call involves an "lvalue-to-rvalue conversion", the other requires an identity conversion (for references) or a "qualification adjustment" (for pointers), and according to the Standard these are treated equally when it comes to overload resolution.
So, neither is better on the basis of differing conversions.
There is, however, a special rule in the Standard, section 13.3.3.2, that applies only if both candidates being compared take the parameter by reference.
Standard conversion sequence `S1` is a better conversion sequence than standard conversion sequence `S2` if ... `S1` and `S2` are reference bindings (8.5.3), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by `S2` refers is more cv-qualified than the type to which the reference initialized by `S1` refers.
There's an identical rule for pointers.
Therefore the compiler will prefer
f(int*);
f(int&);
over
f(const int*);
f(const int&);
respectively, but there's no preference for `f(int)` vs `f(const int)` vs `f(const int&)`, because lvalue-to-rvalue transformation and qualification adjustment are both considered "Exact Match".
Also relevant, from section 13.3.3.1.4:
When a parameter of reference type binds directly to an argument expression, the implicit conversion sequence is the identity conversion, unless the argument expression has a type that is a derived class of the parameter type, in which case the implicit conversion sequence is a derived-to-base Conversion.
Problem
I have a question regarding the c++ function matching for parameters of types `T` and `const T&`. Let's say I have the following two functions: ``` void f(int i) {} void f(const int &ri) {} ``` If I call `f` with an argument of type `const int` then this call is of course ambiguous. But why is a call of `f` with an argument of type `int` also ambiguous? Wouldn't be the first version of `f` be an exact match and the second one a worse match, because the `int` argument must be converted to a `const int`? ``` const int ci = 0; int i = 0; f(ci); // of course ambiguous f(i); // why also ambiguous? ``` I know that such kind of overloading doesn't make much sense, because calls of `f` are almost always ambiguous unless the parameter type T doesn't have an accessible copy constructor. But I'm just studying the rules of function matching. Regards, Kevin EDIT: To make my question more clear. If I have the two functions: ``` void f(int *pi) {} void f(const int *pi) {} ``` Then the following call is not ambiguous: ``` int i = 0; f(&i); // not ambiguous, first version f(int*) chosen ``` Although both versions of `f` could be called with `&i` the first version is chosen, because the second version of `f` would include a conversion to `const.` That is, the first version is a "better match". But in the two functions: ``` void f(int i) {} and void f(const int &ri) {} ``` This additional conversion to `const` seems to be ignored for some reason. Again both versions of `f` could be called with an `int`. But again, the second version of `f` would require a conversion to `const` which would make it a worse match than the first version `f(int).` ``` int i = 1; // f(int) requires no conversion // f(const int &) does require a const conversion // so why are both versions treated as "equally good" matches? // isnt this analogous to the f(int*) and f(const int*) example? f(i); // why ambiguous this time? ```