tmp/tmphtx6447q/{from.md → to.md}
RENAMED
|
@@ -9,58 +9,67 @@ conversions ([[expr.cast]], [[expr.static.cast]]).
|
|
| 9 |
User-defined conversions are applied only where they are unambiguous (
|
| 10 |
[[class.member.lookup]], [[class.conv.fct]]). Conversions obey the
|
| 11 |
access control rules (Clause [[class.access]]). Access control is
|
| 12 |
applied after ambiguity resolution ([[basic.lookup]]).
|
| 13 |
|
| 14 |
-
See [[over.match]] for a discussion of the use of
|
| 15 |
-
function calls as well as examples below.
|
| 16 |
|
| 17 |
At most one user-defined conversion (constructor or conversion function)
|
| 18 |
is implicitly applied to a single value.
|
| 19 |
|
|
|
|
|
|
|
| 20 |
``` cpp
|
| 21 |
struct X {
|
| 22 |
operator int();
|
| 23 |
};
|
| 24 |
|
| 25 |
struct Y {
|
| 26 |
operator X();
|
| 27 |
};
|
| 28 |
|
| 29 |
Y a;
|
| 30 |
-
int b = a; // error
|
| 31 |
-
// a.operator X().operator int() not tried
|
| 32 |
int c = X(a); // OK: a.operator X().operator int()
|
| 33 |
```
|
| 34 |
|
|
|
|
|
|
|
| 35 |
User-defined conversions are used implicitly only if they are
|
| 36 |
unambiguous. A conversion function in a derived class does not hide a
|
| 37 |
conversion function in a base class unless the two functions convert to
|
| 38 |
the same type. Function overload resolution ([[over.match.best]])
|
| 39 |
selects the best conversion function to perform the conversion.
|
| 40 |
|
|
|
|
|
|
|
| 41 |
``` cpp
|
| 42 |
struct X {
|
| 43 |
operator int();
|
| 44 |
};
|
| 45 |
|
| 46 |
struct Y : X {
|
| 47 |
operator char();
|
| 48 |
};
|
| 49 |
|
| 50 |
void f(Y& a) {
|
| 51 |
-
if (a) { // ill-formed:
|
| 52 |
-
// X::operator int() or Y::operator char()
|
| 53 |
}
|
| 54 |
}
|
| 55 |
```
|
| 56 |
|
|
|
|
|
|
|
| 57 |
### Conversion by constructor <a id="class.conv.ctor">[[class.conv.ctor]]</a>
|
| 58 |
|
| 59 |
A constructor declared without the *function-specifier* `explicit`
|
| 60 |
-
specifies a conversion from the types of its parameters
|
| 61 |
-
its class. Such a constructor is called a *converting
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
``` cpp
|
| 64 |
struct X {
|
| 65 |
X(int);
|
| 66 |
X(const char*, int =0);
|
|
@@ -74,37 +83,52 @@ void f(X arg) {
|
|
| 74 |
f(3); // f(X(3))
|
| 75 |
f({1, 2}); // f(X(1,2))
|
| 76 |
}
|
| 77 |
```
|
| 78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
An explicit constructor constructs objects just like non-explicit
|
| 80 |
constructors, but does so only where the direct-initialization syntax (
|
| 81 |
[[dcl.init]]) or where casts ([[expr.static.cast]], [[expr.cast]]) are
|
| 82 |
-
explicitly used. A default constructor
|
| 83 |
-
such a constructor will be used to
|
| 84 |
-
value-initialization ([[dcl.init]]).
|
|
|
|
|
|
|
| 85 |
|
| 86 |
``` cpp
|
| 87 |
struct Z {
|
| 88 |
explicit Z();
|
| 89 |
explicit Z(int);
|
| 90 |
explicit Z(int, int);
|
| 91 |
};
|
| 92 |
|
| 93 |
Z a; // OK: default-initialization performed
|
|
|
|
|
|
|
| 94 |
Z a1 = 1; // error: no implicit conversion
|
| 95 |
Z a3 = Z(1); // OK: direct initialization syntax used
|
| 96 |
Z a2(1); // OK: direct initialization syntax used
|
| 97 |
Z* p = new Z(1); // OK: direct initialization syntax used
|
| 98 |
Z a4 = (Z)1; // OK: explicit cast used
|
| 99 |
Z a5 = static_cast<Z>(1); // OK: explicit cast used
|
| 100 |
Z a6 = { 3, 4 }; // error: no implicit conversion
|
| 101 |
```
|
| 102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
A non-explicit copy/move constructor ([[class.copy]]) is a converting
|
| 104 |
-
constructor.
|
| 105 |
-
|
|
|
|
|
|
|
|
|
|
| 106 |
|
| 107 |
### Conversion functions <a id="class.conv.fct">[[class.conv.fct]]</a>
|
| 108 |
|
| 109 |
A member function of a class `X` having no parameters with a name of the
|
| 110 |
form
|
|
@@ -123,22 +147,26 @@ conversion-type-id:
|
|
| 123 |
conversion-declarator:
|
| 124 |
ptr-operator conversion-declaratorₒₚₜ
|
| 125 |
```
|
| 126 |
|
| 127 |
specifies a conversion from `X` to the type specified by the
|
| 128 |
-
*conversion-type-id*. Such functions are called conversion functions.
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
reference to it), or to
|
|
|
|
|
|
|
|
|
|
| 136 |
|
| 137 |
``` cpp
|
| 138 |
struct X {
|
| 139 |
operator int();
|
|
|
|
| 140 |
};
|
| 141 |
|
| 142 |
void f(X a) {
|
| 143 |
int i = int(a);
|
| 144 |
i = (int)a;
|
|
@@ -147,16 +175,20 @@ void f(X a) {
|
|
| 147 |
```
|
| 148 |
|
| 149 |
In all three cases the value assigned will be converted by
|
| 150 |
`X::operator int()`.
|
| 151 |
|
|
|
|
|
|
|
| 152 |
A conversion function may be explicit ([[dcl.fct.spec]]), in which case
|
| 153 |
it is only considered as a user-defined conversion for
|
| 154 |
direct-initialization ([[dcl.init]]). Otherwise, user-defined
|
| 155 |
conversions are not restricted to use in assignments and
|
| 156 |
initializations.
|
| 157 |
|
|
|
|
|
|
|
| 158 |
``` cpp
|
| 159 |
class Y { };
|
| 160 |
struct Z {
|
| 161 |
explicit operator Y() const;
|
| 162 |
};
|
|
@@ -173,25 +205,60 @@ void g(X a, X b) {
|
|
| 173 |
if (a) {
|
| 174 |
}
|
| 175 |
}
|
| 176 |
```
|
| 177 |
|
|
|
|
|
|
|
| 178 |
The *conversion-type-id* shall not represent a function type nor an
|
| 179 |
array type. The *conversion-type-id* in a *conversion-function-id* is
|
| 180 |
-
the longest
|
| 181 |
-
|
| 182 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
|
| 184 |
``` cpp
|
| 185 |
&ac.operator int*i; // syntax error:
|
| 186 |
// parsed as: &(ac.operator int *)i
|
| 187 |
// not as: &(ac.operator int)*i
|
| 188 |
```
|
| 189 |
|
| 190 |
The `*` is the pointer declarator and not the multiplication operator.
|
| 191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
Conversion functions are inherited.
|
| 193 |
|
| 194 |
Conversion functions can be virtual.
|
| 195 |
|
| 196 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
|
|
|
|
| 9 |
User-defined conversions are applied only where they are unambiguous (
|
| 10 |
[[class.member.lookup]], [[class.conv.fct]]). Conversions obey the
|
| 11 |
access control rules (Clause [[class.access]]). Access control is
|
| 12 |
applied after 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 |
|
| 17 |
At most one user-defined conversion (constructor or conversion function)
|
| 18 |
is implicitly applied to a single value.
|
| 19 |
|
| 20 |
+
[*Example 1*:
|
| 21 |
+
|
| 22 |
``` cpp
|
| 23 |
struct X {
|
| 24 |
operator int();
|
| 25 |
};
|
| 26 |
|
| 27 |
struct Y {
|
| 28 |
operator X();
|
| 29 |
};
|
| 30 |
|
| 31 |
Y a;
|
| 32 |
+
int b = a; // error, a.operator X().operator int() not tried
|
|
|
|
| 33 |
int c = X(a); // OK: a.operator X().operator int()
|
| 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]])
|
| 42 |
selects 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) { // ill-formed: X::operator int() or Y::operator char()
|
|
|
|
| 57 |
}
|
| 58 |
}
|
| 59 |
```
|
| 60 |
|
| 61 |
+
— *end example*]
|
| 62 |
+
|
| 63 |
### Conversion by constructor <a id="class.conv.ctor">[[class.conv.ctor]]</a>
|
| 64 |
|
| 65 |
A constructor declared without the *function-specifier* `explicit`
|
| 66 |
+
specifies a conversion from the types of its parameters (if any) to the
|
| 67 |
+
type of its class. Such a constructor is called a *converting
|
| 68 |
+
constructor*.
|
| 69 |
+
|
| 70 |
+
[*Example 1*:
|
| 71 |
|
| 72 |
``` cpp
|
| 73 |
struct X {
|
| 74 |
X(int);
|
| 75 |
X(const char*, int =0);
|
|
|
|
| 83 |
f(3); // f(X(3))
|
| 84 |
f({1, 2}); // f(X(1,2))
|
| 85 |
}
|
| 86 |
```
|
| 87 |
|
| 88 |
+
— *end example*]
|
| 89 |
+
|
| 90 |
+
[*Note 1*:
|
| 91 |
+
|
| 92 |
An explicit constructor constructs objects just like non-explicit
|
| 93 |
constructors, but does so only where the direct-initialization syntax (
|
| 94 |
[[dcl.init]]) or where casts ([[expr.static.cast]], [[expr.cast]]) are
|
| 95 |
+
explicitly used; see also [[over.match.copy]]. A default constructor
|
| 96 |
+
may be an explicit constructor; such a constructor will be used to
|
| 97 |
+
perform default-initialization or value-initialization ([[dcl.init]]).
|
| 98 |
+
|
| 99 |
+
[*Example 2*:
|
| 100 |
|
| 101 |
``` cpp
|
| 102 |
struct Z {
|
| 103 |
explicit Z();
|
| 104 |
explicit Z(int);
|
| 105 |
explicit Z(int, int);
|
| 106 |
};
|
| 107 |
|
| 108 |
Z a; // OK: default-initialization performed
|
| 109 |
+
Z b{}; // OK: direct initialization syntax used
|
| 110 |
+
Z c = {}; // error: copy-list-initialization
|
| 111 |
Z a1 = 1; // error: no implicit conversion
|
| 112 |
Z a3 = Z(1); // OK: direct initialization syntax used
|
| 113 |
Z a2(1); // OK: direct initialization syntax used
|
| 114 |
Z* p = new Z(1); // OK: direct initialization syntax used
|
| 115 |
Z a4 = (Z)1; // OK: explicit cast used
|
| 116 |
Z a5 = static_cast<Z>(1); // OK: explicit cast used
|
| 117 |
Z a6 = { 3, 4 }; // error: no implicit conversion
|
| 118 |
```
|
| 119 |
|
| 120 |
+
— *end example*]
|
| 121 |
+
|
| 122 |
+
— *end note*]
|
| 123 |
+
|
| 124 |
A non-explicit copy/move constructor ([[class.copy]]) is a converting
|
| 125 |
+
constructor.
|
| 126 |
+
|
| 127 |
+
[*Note 2*: An implicitly-declared copy/move constructor is not an
|
| 128 |
+
explicit constructor; it may be called for implicit type
|
| 129 |
+
conversions. — *end note*]
|
| 130 |
|
| 131 |
### Conversion functions <a id="class.conv.fct">[[class.conv.fct]]</a>
|
| 132 |
|
| 133 |
A member function of a class `X` having no parameters with a name of the
|
| 134 |
form
|
|
|
|
| 147 |
conversion-declarator:
|
| 148 |
ptr-operator conversion-declaratorₒₚₜ
|
| 149 |
```
|
| 150 |
|
| 151 |
specifies a conversion from `X` to the type specified by the
|
| 152 |
+
*conversion-type-id*. Such functions are called *conversion functions*.
|
| 153 |
+
A *decl-specifier* in the *decl-specifier-seq* of a conversion function
|
| 154 |
+
(if any) shall be neither a *defining-type-specifier* nor `static`. The
|
| 155 |
+
type of the conversion function ([[dcl.fct]]) is “function taking no
|
| 156 |
+
parameter returning *conversion-type-id*”. A conversion function is
|
| 157 |
+
never used to convert a (possibly cv-qualified) object to the (possibly
|
| 158 |
+
cv-qualified) same object type (or a reference to it), to a (possibly
|
| 159 |
+
cv-qualified) base class of that type (or a reference to it), or to
|
| 160 |
+
(possibly cv-qualified) void.[^2]
|
| 161 |
+
|
| 162 |
+
[*Example 1*:
|
| 163 |
|
| 164 |
``` cpp
|
| 165 |
struct X {
|
| 166 |
operator int();
|
| 167 |
+
operator auto() -> short; // error: trailing return type
|
| 168 |
};
|
| 169 |
|
| 170 |
void f(X a) {
|
| 171 |
int i = int(a);
|
| 172 |
i = (int)a;
|
|
|
|
| 175 |
```
|
| 176 |
|
| 177 |
In all three cases the value assigned will be converted by
|
| 178 |
`X::operator int()`.
|
| 179 |
|
| 180 |
+
— *end example*]
|
| 181 |
+
|
| 182 |
A conversion function may be explicit ([[dcl.fct.spec]]), in which case
|
| 183 |
it is only considered as a user-defined conversion for
|
| 184 |
direct-initialization ([[dcl.init]]). Otherwise, user-defined
|
| 185 |
conversions are not restricted to use in assignments and
|
| 186 |
initializations.
|
| 187 |
|
| 188 |
+
[*Example 2*:
|
| 189 |
+
|
| 190 |
``` cpp
|
| 191 |
class Y { };
|
| 192 |
struct Z {
|
| 193 |
explicit operator Y() const;
|
| 194 |
};
|
|
|
|
| 205 |
if (a) {
|
| 206 |
}
|
| 207 |
}
|
| 208 |
```
|
| 209 |
|
| 210 |
+
— *end example*]
|
| 211 |
+
|
| 212 |
The *conversion-type-id* shall not represent a function type nor an
|
| 213 |
array type. The *conversion-type-id* in a *conversion-function-id* is
|
| 214 |
+
the longest sequence of tokens that could possibly form a
|
| 215 |
+
*conversion-type-id*.
|
| 216 |
+
|
| 217 |
+
[*Note 1*:
|
| 218 |
+
|
| 219 |
+
This prevents ambiguities between the declarator operator `*` and its
|
| 220 |
+
expression counterparts.
|
| 221 |
+
|
| 222 |
+
[*Example 3*:
|
| 223 |
|
| 224 |
``` cpp
|
| 225 |
&ac.operator int*i; // syntax error:
|
| 226 |
// parsed as: &(ac.operator int *)i
|
| 227 |
// not as: &(ac.operator int)*i
|
| 228 |
```
|
| 229 |
|
| 230 |
The `*` is the pointer declarator and not the multiplication operator.
|
| 231 |
|
| 232 |
+
— *end example*]
|
| 233 |
+
|
| 234 |
+
This rule also prevents ambiguities for attributes.
|
| 235 |
+
|
| 236 |
+
[*Example 4*:
|
| 237 |
+
|
| 238 |
+
``` cpp
|
| 239 |
+
operator int [[noreturn]] (); // error: noreturn attribute applied to a type
|
| 240 |
+
```
|
| 241 |
+
|
| 242 |
+
— *end example*]
|
| 243 |
+
|
| 244 |
+
— *end note*]
|
| 245 |
+
|
| 246 |
Conversion functions are inherited.
|
| 247 |
|
| 248 |
Conversion functions can be virtual.
|
| 249 |
|
| 250 |
+
A conversion function template shall not have a deduced return type (
|
| 251 |
+
[[dcl.spec.auto]]).
|
| 252 |
+
|
| 253 |
+
[*Example 5*:
|
| 254 |
+
|
| 255 |
+
``` cpp
|
| 256 |
+
struct S {
|
| 257 |
+
operator auto() const { return 10; } // OK
|
| 258 |
+
template<class T>
|
| 259 |
+
operator auto() const { return 1.2; } // error: conversion function template
|
| 260 |
+
};
|
| 261 |
+
```
|
| 262 |
+
|
| 263 |
+
— *end example*]
|
| 264 |
|