I have the following code snippet:
struct T {
T(const T&) = default;
T(const S &);
};
struct S {
operator T();
};
int main() {
S s;
T t = s; // copy-initialization of class type
return 0;
}
My question is why the compiler prefers S::operator T() for the initialization of t rather than reporting an error that the initialization is ambigious. In my opinion the following happens (correct me if i am wrong):
- t is copy-initialized with an lvalue of type S
- S is not T and S is also not a subclass of T, so S and T are unrelated
- because of the fact that the variable t is copy-initialized and the fact that the types S and T are unrelated, the compiler tries to find user-defined-conversion sequences to do the initialization.
- overload resolution is responsible for selecting the best user-defined-conversion which can be either a converting constructor of T or the conversion function of S
- the implicite conversion sequence for the constructor T::T(const S&) from the argument s is the identity conversion because the lvalue s can be bound directly to this lvalue reference
- the implicite conversion sequence for the conversion function S::operator T() from the argument s is also the identity conversion, because the implicit object parameter is S&
Both the constructor and the conversion function return a prvalue of type T which can be used to direct-initialize the variable t. That means that the second standard conversion sequence of both user-defined-conversion sequences is the identity conversion.
This would mean that both user-defined-conversion sequences are equally good. Or is there a special rule which prefers the conversion functions?
I was reading the following rules in the c++11 standard:
The initialization that occurs in the form T x = a; as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1) is called copy-initialization.
The semantics of initializers are as follows...If the destination type is a (possibly cv-qualified) class type: If the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered.... Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in 13.3.1.4, and the best one is chosen through overload resolution (13.3)
User-defined conversion sequence U1 is a better conversion sequence than another user defined conversion sequence U2 if they contain the same user-defined conversion function or constructor and if the second standard conversion sequence of U1 is better than the second standard conversion sequence of U2
Maybe i am making false assumptions. I hope you can help me!