[class.conv] (original) (raw)
11 Classes [class]
11.4 Class members [class.mem]
11.4.7 Conversions [class.conv]
Type conversions of class objects can be specified by constructors and by conversion functions.
[ Note
:
See [over.match] for a discussion of the use of conversions in function calls as well as examples below.
— end note
]
At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.
[ Example
:
struct X { operator int(); };
struct Y { operator X(); };
Y a;
int b = a;
int c = X(a);
— end example
]
User-defined conversions are used implicitly only if they are unambiguous.
A conversion function in a derived class does not hide a conversion function in a base class unless the two functions convert to the same type.
Function overload resolution ([over.match.best]) selects the best conversion function to perform the conversion.
[ Example
:
struct X { operator int(); };
struct Y : X { operator char(); };
void f(Y& a) {
if (a) {
}
}
— end example
]
11.4.7.1 Conversion by constructor [class.conv.ctor]
A constructor that is not explicit ([dcl.fct.spec]) specifies a conversion from the types of its parameters (if any) to the type of its class.
Such a constructor is called aconverting constructor.
[ Example
:
struct X { X(int); X(const char*, int =0); X(int, int); };
void f(X arg) {
X a = 1;
X b = "Jessie";
a = 2;
f(3);
f({1, 2});
}
— end example
]
[ Note
:
An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax ([dcl.init]) or where casts ([expr.static.cast], [expr.cast]) are explicitly used; see also [over.match.copy].
A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization or value-initialization ([dcl.init]).
[ Example
:
struct Z { explicit Z(); explicit Z(int); explicit Z(int, int); };
Z a;
Z b{};
Z c = {};
Z a1 = 1;
Z a3 = Z(1);
Z a2(1);
Z* p = new Z(1);
Z a4 = (Z)1;
Z a5 = static_cast(1);
Z a6 = { 3, 4 };
— end example
]
— end note
]
A non-explicit copy/move constructor ([class.copy.ctor]) is a converting constructor.
[ Note
:
An implicitly-declared copy/move constructor is not an explicit constructor; it may be called for implicit type conversions.
— end note
]
11.4.7.2 Conversion functions [class.conv.fct]
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-declarator
Such functions are called conversion functions.
The type of the conversion function ([dcl.fct]) is “function taking no parameter returningconversion-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 cv void.106
[ Example
:
struct X {
operator int();
operator auto() -> short;
};
void f(X a) { int i = int(a); i = (int)a; i = a; }
In all three cases the value assigned will be converted byX::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);
Y y2 = z;
Y y3 = (Y)z;
}
void g(X a, X b) { int i = (a) ? 1+a : 0; int j = (a&&b) ? a+b : i; if (a) { } }
— end example
]
Theconversion-type-idshall not represent a function type nor an array type.
Theconversion-type-idin aconversion-function-idis the longest sequence of tokens that could possibly form a conversion-type-id.
[ Note
:
This prevents ambiguities between the declarator operator * and its expression counterparts.
[ Example
:
&ac.operator int*i;
The * is the pointer declarator and not the multiplication operator.
— end example
]
This rule also prevents ambiguities for attributes.
[ Example
:
operator int [[noreturn]] ();
— end example
]
— end note
]
Conversion functions are inherited.
Conversion functions can be virtual.
A conversion function template shall not have a deduced return type ([dcl.spec.auto]).
[ Example
:
struct S {
operator auto() const { return 10; }
template
operator auto() const { return 1.2; }
};
— end example
]