tmp/tmpxpkhsn4c/{from.md → to.md}
RENAMED
|
@@ -1,16 +1,18 @@
|
|
| 1 |
### Conversions <a id="class.conv">[[class.conv]]</a>
|
| 2 |
|
|
|
|
|
|
|
| 3 |
Type conversions of class objects can be specified by constructors and
|
| 4 |
by conversion functions. These conversions are called *user-defined
|
| 5 |
conversions* and are used for implicit type conversions [[conv]], for
|
| 6 |
-
initialization [[dcl.init]], and for explicit type conversions
|
| 7 |
-
[[expr.type.conv]], [[expr.cast]], [[expr.static.cast]]
|
| 8 |
|
| 9 |
-
User-defined conversions are applied only where they are unambiguous
|
| 10 |
-
[[class.member.lookup]], [[class.conv.fct]]
|
| 11 |
-
|
| 12 |
ambiguity resolution [[basic.lookup]].
|
| 13 |
|
| 14 |
[*Note 1*: See [[over.match]] for a discussion of the use of
|
| 15 |
conversions in function calls as well as examples below. — *end note*]
|
| 16 |
|
|
@@ -28,36 +30,11 @@ struct Y {
|
|
| 28 |
operator X();
|
| 29 |
};
|
| 30 |
|
| 31 |
Y a;
|
| 32 |
int b = a; // error: no viable conversion (a.operator X().operator int() not considered)
|
| 33 |
-
int c = X(a); // OK
|
| 34 |
-
```
|
| 35 |
-
|
| 36 |
-
— *end example*]
|
| 37 |
-
|
| 38 |
-
User-defined conversions are used implicitly only if they are
|
| 39 |
-
unambiguous. A conversion function in a derived class does not hide a
|
| 40 |
-
conversion function in a base class unless the two functions convert to
|
| 41 |
-
the same type. Function overload resolution [[over.match.best]] selects
|
| 42 |
-
the best conversion function to perform the conversion.
|
| 43 |
-
|
| 44 |
-
[*Example 2*:
|
| 45 |
-
|
| 46 |
-
``` cpp
|
| 47 |
-
struct X {
|
| 48 |
-
operator int();
|
| 49 |
-
};
|
| 50 |
-
|
| 51 |
-
struct Y : X {
|
| 52 |
-
operator char();
|
| 53 |
-
};
|
| 54 |
-
|
| 55 |
-
void f(Y& a) {
|
| 56 |
-
if (a) { // error: ambiguous between X::operator int() and Y::operator char()
|
| 57 |
-
}
|
| 58 |
-
}
|
| 59 |
```
|
| 60 |
|
| 61 |
— *end example*]
|
| 62 |
|
| 63 |
#### Conversion by constructor <a id="class.conv.ctor">[[class.conv.ctor]]</a>
|
|
@@ -88,13 +65,13 @@ void f(X arg) {
|
|
| 88 |
|
| 89 |
[*Note 1*:
|
| 90 |
|
| 91 |
An explicit constructor constructs objects just like non-explicit
|
| 92 |
constructors, but does so only where the direct-initialization syntax
|
| 93 |
-
[[dcl.init]] or where casts
|
| 94 |
explicitly used; see also [[over.match.copy]]. A default constructor
|
| 95 |
-
|
| 96 |
perform default-initialization or value-initialization [[dcl.init]].
|
| 97 |
|
| 98 |
[*Example 2*:
|
| 99 |
|
| 100 |
``` cpp
|
|
@@ -102,19 +79,19 @@ struct Z {
|
|
| 102 |
explicit Z();
|
| 103 |
explicit Z(int);
|
| 104 |
explicit Z(int, int);
|
| 105 |
};
|
| 106 |
|
| 107 |
-
Z a; // OK
|
| 108 |
-
Z b{}; // OK
|
| 109 |
Z c = {}; // error: copy-list-initialization
|
| 110 |
Z a1 = 1; // error: no implicit conversion
|
| 111 |
-
Z a3 = Z(1); // OK
|
| 112 |
-
Z a2(1); // OK
|
| 113 |
-
Z* p = new Z(1); // OK
|
| 114 |
-
Z a4 = (Z)1; // OK
|
| 115 |
-
Z a5 = static_cast<Z>(1); // OK
|
| 116 |
Z a6 = { 3, 4 }; // error: no implicit conversion
|
| 117 |
```
|
| 118 |
|
| 119 |
— *end example*]
|
| 120 |
|
|
@@ -122,18 +99,15 @@ Z a6 = { 3, 4 }; // error: no implicit conversion
|
|
| 122 |
|
| 123 |
A non-explicit copy/move constructor [[class.copy.ctor]] is a converting
|
| 124 |
constructor.
|
| 125 |
|
| 126 |
[*Note 2*: An implicitly-declared copy/move constructor is not an
|
| 127 |
-
explicit constructor; it
|
| 128 |
conversions. — *end note*]
|
| 129 |
|
| 130 |
#### Conversion functions <a id="class.conv.fct">[[class.conv.fct]]</a>
|
| 131 |
|
| 132 |
-
A member function of a class `X` having no parameters with a name of the
|
| 133 |
-
form
|
| 134 |
-
|
| 135 |
``` bnf
|
| 136 |
conversion-function-id:
|
| 137 |
operator conversion-type-id
|
| 138 |
```
|
| 139 |
|
|
@@ -145,20 +119,44 @@ conversion-type-id:
|
|
| 145 |
``` bnf
|
| 146 |
conversion-declarator:
|
| 147 |
ptr-operator conversion-declaratorₒₚₜ
|
| 148 |
```
|
| 149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
specifies a conversion from `X` to the type specified by the
|
| 151 |
-
*conversion-type-id*
|
| 152 |
-
|
| 153 |
-
(if any) shall be
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
cv
|
|
|
|
|
|
|
|
|
|
| 160 |
|
| 161 |
[*Example 1*:
|
| 162 |
|
| 163 |
``` cpp
|
| 164 |
struct X {
|
|
@@ -190,13 +188,13 @@ class Y { };
|
|
| 190 |
struct Z {
|
| 191 |
explicit operator Y() const;
|
| 192 |
};
|
| 193 |
|
| 194 |
void h(Z z) {
|
| 195 |
-
Y y1(z); // OK
|
| 196 |
Y y2 = z; // error: no conversion function candidate for copy-initialization
|
| 197 |
-
Y y3 = (Y)z; // OK
|
| 198 |
}
|
| 199 |
|
| 200 |
void g(X a, X b) {
|
| 201 |
int i = (a) ? 1+a : 0;
|
| 202 |
int j = (a&&b) ? a+b : i;
|
|
@@ -239,18 +237,47 @@ operator int [[noreturn]] (); // error: noreturn attribute applied to a type
|
|
| 239 |
|
| 240 |
— *end example*]
|
| 241 |
|
| 242 |
— *end note*]
|
| 243 |
|
| 244 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 245 |
|
| 246 |
Conversion functions can be virtual.
|
| 247 |
|
| 248 |
A conversion function template shall not have a deduced return type
|
| 249 |
[[dcl.spec.auto]].
|
| 250 |
|
| 251 |
-
[*Example
|
| 252 |
|
| 253 |
``` cpp
|
| 254 |
struct S {
|
| 255 |
operator auto() const { return 10; } // OK
|
| 256 |
template<class T>
|
|
|
|
| 1 |
### Conversions <a id="class.conv">[[class.conv]]</a>
|
| 2 |
|
| 3 |
+
#### General <a id="class.conv.general">[[class.conv.general]]</a>
|
| 4 |
+
|
| 5 |
Type conversions of class objects can be specified by constructors and
|
| 6 |
by conversion functions. These conversions are called *user-defined
|
| 7 |
conversions* and are used for implicit type conversions [[conv]], for
|
| 8 |
+
initialization [[dcl.init]], and for explicit type conversions
|
| 9 |
+
[[expr.type.conv]], [[expr.cast]], [[expr.static.cast]].
|
| 10 |
|
| 11 |
+
User-defined conversions are applied only where they are unambiguous
|
| 12 |
+
[[class.member.lookup]], [[class.conv.fct]]. Conversions obey the access
|
| 13 |
+
control rules [[class.access]]. Access control is applied after
|
| 14 |
ambiguity resolution [[basic.lookup]].
|
| 15 |
|
| 16 |
[*Note 1*: See [[over.match]] for a discussion of the use of
|
| 17 |
conversions in function calls as well as examples below. — *end note*]
|
| 18 |
|
|
|
|
| 30 |
operator X();
|
| 31 |
};
|
| 32 |
|
| 33 |
Y a;
|
| 34 |
int b = a; // error: no viable conversion (a.operator X().operator int() not considered)
|
| 35 |
+
int c = X(a); // OK, a.operator X().operator int()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
```
|
| 37 |
|
| 38 |
— *end example*]
|
| 39 |
|
| 40 |
#### Conversion by constructor <a id="class.conv.ctor">[[class.conv.ctor]]</a>
|
|
|
|
| 65 |
|
| 66 |
[*Note 1*:
|
| 67 |
|
| 68 |
An explicit constructor constructs objects just like non-explicit
|
| 69 |
constructors, but does so only where the direct-initialization syntax
|
| 70 |
+
[[dcl.init]] or where casts [[expr.static.cast]], [[expr.cast]] are
|
| 71 |
explicitly used; see also [[over.match.copy]]. A default constructor
|
| 72 |
+
can be an explicit constructor; such a constructor will be used to
|
| 73 |
perform default-initialization or value-initialization [[dcl.init]].
|
| 74 |
|
| 75 |
[*Example 2*:
|
| 76 |
|
| 77 |
``` cpp
|
|
|
|
| 79 |
explicit Z();
|
| 80 |
explicit Z(int);
|
| 81 |
explicit Z(int, int);
|
| 82 |
};
|
| 83 |
|
| 84 |
+
Z a; // OK, default-initialization performed
|
| 85 |
+
Z b{}; // OK, direct initialization syntax used
|
| 86 |
Z c = {}; // error: copy-list-initialization
|
| 87 |
Z a1 = 1; // error: no implicit conversion
|
| 88 |
+
Z a3 = Z(1); // OK, direct initialization syntax used
|
| 89 |
+
Z a2(1); // OK, direct initialization syntax used
|
| 90 |
+
Z* p = new Z(1); // OK, direct initialization syntax used
|
| 91 |
+
Z a4 = (Z)1; // OK, explicit cast used
|
| 92 |
+
Z a5 = static_cast<Z>(1); // OK, explicit cast used
|
| 93 |
Z a6 = { 3, 4 }; // error: no implicit conversion
|
| 94 |
```
|
| 95 |
|
| 96 |
— *end example*]
|
| 97 |
|
|
|
|
| 99 |
|
| 100 |
A non-explicit copy/move constructor [[class.copy.ctor]] is a converting
|
| 101 |
constructor.
|
| 102 |
|
| 103 |
[*Note 2*: An implicitly-declared copy/move constructor is not an
|
| 104 |
+
explicit constructor; it can be called for implicit type
|
| 105 |
conversions. — *end note*]
|
| 106 |
|
| 107 |
#### Conversion functions <a id="class.conv.fct">[[class.conv.fct]]</a>
|
| 108 |
|
|
|
|
|
|
|
|
|
|
| 109 |
``` bnf
|
| 110 |
conversion-function-id:
|
| 111 |
operator conversion-type-id
|
| 112 |
```
|
| 113 |
|
|
|
|
| 119 |
``` bnf
|
| 120 |
conversion-declarator:
|
| 121 |
ptr-operator conversion-declaratorₒₚₜ
|
| 122 |
```
|
| 123 |
|
| 124 |
+
A declaration whose *declarator-id* has an *unqualified-id* that is a
|
| 125 |
+
*conversion-function-id* declares a *conversion function*; its
|
| 126 |
+
*declarator* shall be a function declarator [[dcl.fct]] of the form
|
| 127 |
+
|
| 128 |
+
``` bnf
|
| 129 |
+
ptr-declarator '(' parameter-declaration-clause ')' cv-qualifier-seqₒₚₜ
|
| 130 |
+
ref-qualifier-seqₒₚₜ noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ
|
| 131 |
+
```
|
| 132 |
+
|
| 133 |
+
where the *ptr-declarator* consists solely of an *id-expression*, an
|
| 134 |
+
optional *attribute-specifier-seq*, and optional surrounding
|
| 135 |
+
parentheses, and the *id-expression* has one of the following forms:
|
| 136 |
+
|
| 137 |
+
- in a *member-declaration* that belongs to the *member-specification*
|
| 138 |
+
of a class or class template but is not a friend declaration
|
| 139 |
+
[[class.friend]], the *id-expression* is a *conversion-function-id*;
|
| 140 |
+
- otherwise, the *id-expression* is a *qualified-id* whose
|
| 141 |
+
*unqualified-id* is a *conversion-function-id*.
|
| 142 |
+
|
| 143 |
+
A conversion function shall have no non-object parameters and shall be a
|
| 144 |
+
non-static member function of a class or class template `X`; it
|
| 145 |
specifies a conversion from `X` to the type specified by the
|
| 146 |
+
*conversion-type-id*, interpreted as a *type-id* [[dcl.name]]. A
|
| 147 |
+
*decl-specifier* in the *decl-specifier-seq* of a conversion function
|
| 148 |
+
(if any) shall not be a *defining-type-specifier*.
|
| 149 |
+
|
| 150 |
+
The type of the conversion function is “`noexcept`ₒₚₜ function taking
|
| 151 |
+
no parameter *cv-qualifier-seq*ₒₚₜ *ref-qualifier*ₒₚₜ returning
|
| 152 |
+
*conversion-type-id*”.
|
| 153 |
+
|
| 154 |
+
A conversion function is never used to convert a (possibly cv-qualified)
|
| 155 |
+
object to the (possibly cv-qualified) same object type (or a reference
|
| 156 |
+
to it), to a (possibly cv-qualified) base class of that type (or a
|
| 157 |
+
reference to it), or to cv `void`.[^6]
|
| 158 |
|
| 159 |
[*Example 1*:
|
| 160 |
|
| 161 |
``` cpp
|
| 162 |
struct X {
|
|
|
|
| 188 |
struct Z {
|
| 189 |
explicit operator Y() const;
|
| 190 |
};
|
| 191 |
|
| 192 |
void h(Z z) {
|
| 193 |
+
Y y1(z); // OK, direct-initialization
|
| 194 |
Y y2 = z; // error: no conversion function candidate for copy-initialization
|
| 195 |
+
Y y3 = (Y)z; // OK, cast notation
|
| 196 |
}
|
| 197 |
|
| 198 |
void g(X a, X b) {
|
| 199 |
int i = (a) ? 1+a : 0;
|
| 200 |
int j = (a&&b) ? a+b : i;
|
|
|
|
| 237 |
|
| 238 |
— *end example*]
|
| 239 |
|
| 240 |
— *end note*]
|
| 241 |
|
| 242 |
+
[*Note 2*:
|
| 243 |
+
|
| 244 |
+
A conversion function in a derived class hides only conversion functions
|
| 245 |
+
in base classes that convert to the same type. A conversion function
|
| 246 |
+
template with a dependent return type hides only templates in base
|
| 247 |
+
classes that correspond to it [[class.member.lookup]]; otherwise, it
|
| 248 |
+
hides and is hidden as a non-template function. Function overload
|
| 249 |
+
resolution [[over.match.best]] selects the best conversion function to
|
| 250 |
+
perform the conversion.
|
| 251 |
+
|
| 252 |
+
[*Example 5*:
|
| 253 |
+
|
| 254 |
+
``` cpp
|
| 255 |
+
struct X {
|
| 256 |
+
operator int();
|
| 257 |
+
};
|
| 258 |
+
|
| 259 |
+
struct Y : X {
|
| 260 |
+
operator char();
|
| 261 |
+
};
|
| 262 |
+
|
| 263 |
+
void f(Y& a) {
|
| 264 |
+
if (a) { // error: ambiguous between X::operator int() and Y::operator char()
|
| 265 |
+
}
|
| 266 |
+
}
|
| 267 |
+
```
|
| 268 |
+
|
| 269 |
+
— *end example*]
|
| 270 |
+
|
| 271 |
+
— *end note*]
|
| 272 |
|
| 273 |
Conversion functions can be virtual.
|
| 274 |
|
| 275 |
A conversion function template shall not have a deduced return type
|
| 276 |
[[dcl.spec.auto]].
|
| 277 |
|
| 278 |
+
[*Example 6*:
|
| 279 |
|
| 280 |
``` cpp
|
| 281 |
struct S {
|
| 282 |
operator auto() const { return 10; } // OK
|
| 283 |
template<class T>
|