Barry Barry - 1 year ago 78
C++ Question

Overloading conversion function templates

Consider the following:

struct X {
template <class T> operator T(); // #1
template <class T> operator T&(); // #2

int a = X{}; // error: ambiguous
int& b = X{}; // calls #2
int const& c = X{}; // calls #2

The situation for
is straightforward,
is the only viable candidate. What is the rule that indicates that
is preferred to
for initialization of
int const&
, but the two are ambiguous for initialization of

Answer Source

When deciding how to initialize a reference given its initializer, first, direct binding is tried. [dcl.init.ref]/(5.1.2):

If the reference is an lvalue reference and the initializer expression […] has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be converted to an lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3” (this conversion is selected by enumerating the applicable conversion functions ( and choosing the best one through overload resolution (13.3)), then the reference is bound […] to the lvalue result of the conversion […].

The wording that governs the candidate selection for this process (, as mentioned above) excludes the first conversion function:

The conversion functions of S and its base classes are considered. Those non-explicit conversion functions that are not hidden within S and yield type “lvalue reference to cv2 T2(when initializing an lvalue reference or an rvalue reference to function) […], where “cv1 T” is reference-compatible (8.6.3) with “cv2 T2”, are candidate functions. For direct-initialization, […].

Clearly, this exclusion is specific to the reference initialization semantics, so the first case is ambiguous still.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download