I found out the rules for determining the candidate conversion functions, for direct reference binding, are not described clearly by the standard at least for me.
The rules are found in [over.match.ref]
Under the conditions specified in [dcl.init.ref], a reference can be bound directly to the result of applying a conversion function to an initializer expression. Overload resolution is used to select the conversion function to be invoked. Assuming that “reference to cv1 T” is the type of the reference being initialized, the candidate functions are selected as follows:
- (1.1) Let R be a set of types including
- (1.1.1) “lvalue reference to cv2 T2” (when initializing an lvalue reference or an rvalue reference to function) and
- (1.1.2) “cv2 T2” and “rvalue reference to cv2 T2” (when initializing an rvalue reference or an lvalue reference to function) for any T2.
The permissible types for non-explicit conversion functions are the members of R where “cv1 T” is reference-compatible ([dcl.init.ref]) with “cv2 T2”. For direct-initialization, the permissible types for explicit conversion functions are the members of R where T2 can be converted to type T with a (possibly trivial) qualification conversion ([conv.qual]); otherwise there are none.
As far as I understood, I can say that when initializing an "lvalue reference to cv1 T" the conversion function is a candidate if and only if it returns "lvalue reference to cv2 T2", where “cv1 T” is reference-compatible with “cv2 T2”.
And when initializing an "rvalue reference to cv1 T", the conversion function is a candidate if and only if it returns "rvalue reference to cv2 T2" or "cv T2", where “cv1 T” is reference-compatible with “cv2 T2”. Right?
Assuming my understanding is correct, here is a question. Why do we even need a conversion function to convert from cv2 T2 to cv1 T even though “cv1 T” is reference-compatible with “cv2 T2”?
Can you clearly explain the bullet (1.1) with some examples?