tl;dr
Ambiguous. (Also, if you're stopping at the tl;dr, then the language-lawyer
tag might not be your cup-of-tea. ^_^)
Spoiler
Both candidates have a single const foo&
parameter, which binds equally to a const foo
or foo
argument. No other rules appear that would prefer one or the other function.
Breaking it down against the current C++ working draft
In both cases
Copy-initialization of class by user-defined conversion [over.match.copy]
T
is the type being intialised, in both cases this is bar
.
S
is the type of the initializer expression, in the two cases foo
and const foo
respectively.
- converting constructors of
T
are candidates ([over.match.copy]/1.1)
bar::bar(const foo& foo);
is a candidate
- the type of the initializer expression is
_cv_ S
so non-explicit conversion functions are considered: ([over.match.copy]/1.2)
foo::operator bar() const
is not hidden within foo
or within const foo
, and yields bar
which is the same as T
, and hence is a candidate.
So our candidate list is the same in both cases:
bar::bar(const foo& foo)
foo::operator bar() const
In both cases, we have a user-defined conversion consisting of:
- Standard conversion of source type to user-defined conversion argument
- User-defined conversion (one of the above two functions) to result type
- Standard conversion of result type to target type
If we select the constructor, the "result type" is "a prvalue of the cv-unqualified version of the destination type whose result object is initialized by the constructor" ([dcl.init]/17.6.3), so for both candidate functions, the second Standard Conversion is Identity (bar
-> bar
).
Subsetting the viable candidate functions [over.match.viable]
Per [dcl.init]/17.6.3, the initializer expression is going to be the argument to the selected call, in the two cases foo
and const foo
respectively.
bar::bar(const foo& foo)
foo::operator bar() const
Select the best viable function [over.best.ics]
Both are Identity => User Defined Conversion => Identity, i.e., are user-defined conversion sequences.
Ranking conversion sequences over.ics.rank
Can we establish a ranking between the sequences? Only if one of the following applies
- (X) Not list-initialization sequences ([over.ics.rank]/3)
- (X) Not a standard conversion sequence ([over.ics.rank]/3.2)
- (X) The two sequences do not contain "the same user-defined conversion function or constructor or [...] initialize the same class in an aggregate initialization" ([over.ics.rank]/3.3)
Conversion sequences are indistinguishable, i.e., neither is better nor worse
Is either function a 'better' function? Only if one of the following applies
Neither is a 'better' function, so the call is ill-formed. [over.match.best]/2