From Jason Turner

[class.conv]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpxpkhsn4c/{from.md → to.md} +84 -57
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]]). Conversions obey the
11
- access control rules [[class.access]]. Access control is applied after
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: 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]] 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 ([[expr.static.cast]], [[expr.cast]]) are
94
  explicitly used; see also  [[over.match.copy]]. A default constructor
95
- may be an explicit constructor; such a constructor will be used to
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: default-initialization performed
108
- Z b{}; // OK: direct initialization syntax used
109
  Z c = {}; // error: copy-list-initialization
110
  Z a1 = 1; // error: no implicit conversion
111
- Z a3 = Z(1); // OK: direct initialization syntax used
112
- Z a2(1); // OK: direct initialization syntax used
113
- Z* p = new Z(1); // OK: direct initialization syntax used
114
- Z a4 = (Z)1; // OK: explicit cast used
115
- Z a5 = static_cast<Z>(1); // OK: explicit cast used
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 may be called for implicit type
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*. Such functions are called *conversion functions*.
152
- A *decl-specifier* in the *decl-specifier-seq* of a conversion function
153
- (if any) shall be neither a *defining-type-specifier* nor `static`. The
154
- type of the conversion function [[dcl.fct]] is “function taking no
155
- parameter returning *conversion-type-id*”. A conversion function is
156
- never used to convert a (possibly cv-qualified) object to the (possibly
157
- cv-qualified) same object type (or a reference to it), to a (possibly
158
- cv-qualified) base class of that type (or a reference to it), or to
159
- cv `void`.[^6]
 
 
 
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: direct-initialization
196
  Y y2 = z; // error: no conversion function candidate for copy-initialization
197
- Y y3 = (Y)z; // OK: cast notation
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
- Conversion functions are inherited.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 5*:
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>