From Jason Turner

[class.conv]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmphtx6447q/{from.md → to.md} +92 -25
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 conversions in
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 to the type of
61
- its class. Such a constructor is called a *converting constructor*.
 
 
 
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 may be an explicit constructor;
83
- such a constructor will be used to perform default-initialization or
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. An implicitly-declared copy/move constructor is not an
105
- explicit constructor; it may be called for implicit type conversions.
 
 
 
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. No
129
- return type can be specified. If a conversion function is a member
130
- function, the type of the conversion function ([[dcl.fct]]) is
131
- “function taking no parameter returning *conversion-type-id*”. A
132
- conversion function is never used to convert a (possibly cv-qualified)
133
- object to the (possibly cv-qualified) same object type (or a reference
134
- to it), to a (possibly cv-qualified) base class of that type (or a
135
- reference to it), or to (possibly cv-qualified) void.[^2]
 
 
 
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 possible sequence of *conversion-declarator*s. This prevents
181
- ambiguities between the declarator operator \* and its expression
182
- counterparts.
 
 
 
 
 
 
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
- Conversion functions cannot be declared `static`.
 
 
 
 
 
 
 
 
 
 
 
 
 
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