A member function of a class X having no parameters with a name of the form
conversion-function-id: operator conversion-type-id
conversion-type-id: type-specifier-seq conversion-declaratoropt
conversion-declarator: ptr-operator conversion-declaratoropt
specifies a conversion from X to the type specified by the conversion-type-id. Such functions are called conversion functions. No return type can be specified. If a conversion function is a member function, the type of the conversion function ([dcl.fct]) is “function taking no parameter returning conversion-type-id”. A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.116
[ Example:
struct X { operator int(); }; void f(X a) { int i = int(a); i = (int)a; i = a; }
In all three cases the value assigned will be converted by X::operator int(). — end example ]
A conversion function may be explicit ([dcl.fct.spec]), in which case it is only considered as a user-defined conversion for direct-initialization ([dcl.init]). Otherwise, user-defined conversions are not restricted to use in assignments and initializations. [ Example:
class Y { }; struct Z { explicit operator Y() const; }; void h(Z z) { Y y1(z); // OK: direct-initialization Y y2 = z; // ill-formed: copy-initialization Y y3 = (Y)z; // OK: cast notation } void g(X a, X b) { int i = (a) ? 1+a : 0; int j = (a&&b) ? a+b : i; if (a) { } }
— end example ]
The conversion-type-id shall not represent a function type nor an array type. The conversion-type-id in a conversion-function-id is the longest possible sequence of conversion-declarators. [ Note: This prevents ambiguities between the declarator operator * and its expression counterparts. [ Example:
&ac.operator int*i; // syntax error: // parsed as: &(ac.operator int *)i // not as: &(ac.operator int)*i
The * is the pointer declarator and not the multiplication operator. — end example ] — end note ]
These conversions are considered as standard conversions for the purposes of overload resolution ([over.best.ics], [over.ics.ref]) and therefore initialization ([dcl.init]) and explicit casts ([expr.static.cast]). A conversion to void does not invoke any conversion function ([expr.static.cast]). Even though never directly called to perform a conversion, such conversion functions can be declared and can potentially be reached through a call to a virtual conversion function in a base class.