From Jason Turner

[class.inhctor]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpo6qjsxs0/{from.md → to.md} +0 -310
tmp/tmpo6qjsxs0/{from.md → to.md} RENAMED
@@ -1,310 +0,0 @@
1
- ## Inheriting constructors <a id="class.inhctor">[[class.inhctor]]</a>
2
-
3
- A *using-declaration* ([[namespace.udecl]]) that names a constructor
4
- implicitly declares a set of *inheriting constructors*. The *candidate
5
- set of inherited constructors* from the class `X` named in the
6
- *using-declaration* consists of actual constructors and notional
7
- constructors that result from the transformation of defaulted parameters
8
- as follows:
9
-
10
- - all non-template constructors of `X`, and
11
- - for each non-template constructor of `X` that has at least one
12
- parameter with a default argument, the set of constructors that
13
- results from omitting any ellipsis parameter specification and
14
- successively omitting parameters with a default argument from the end
15
- of the parameter-type-list, and
16
- - all constructor templates of `X`, and
17
- - for each constructor template of `X` that has at least one parameter
18
- with a default argument, the set of constructor templates that results
19
- from omitting any ellipsis parameter specification and successively
20
- omitting parameters with a default argument from the end of the
21
- parameter-type-list.
22
-
23
- The *constructor characteristics* of a constructor or constructor
24
- template are
25
-
26
- - the template parameter list ([[temp.param]]), if any,
27
- - the *parameter-type-list* ([[dcl.fct]]),
28
- - absence or presence of `explicit` ([[class.conv.ctor]]), and
29
- - absence or presence of `constexpr` ([[dcl.constexpr]]).
30
-
31
- For each non-template constructor in the candidate set of inherited
32
- constructors other than a constructor having no parameters or a
33
- copy/move constructor having a single parameter, a constructor is
34
- implicitly declared with the same constructor characteristics unless
35
- there is a user-declared constructor with the same signature in the
36
- complete class where the *using-declaration* appears or the constructor
37
- would be a default, copy, or move constructor for that class. Similarly,
38
- for each constructor template in the candidate set of inherited
39
- constructors, a constructor template is implicitly declared with the
40
- same constructor characteristics unless there is an equivalent
41
- user-declared constructor template ([[temp.over.link]]) in the complete
42
- class where the *using-declaration* appears. Default arguments are not
43
- inherited. An *exception-specification* is implied as specified in 
44
- [[except.spec]].
45
-
46
- A constructor so declared has the same access as the corresponding
47
- constructor in `X`. It is deleted if the corresponding constructor in
48
- `X` is deleted ([[dcl.fct.def]]). An inheriting constructor shall not
49
- be explicitly instantiated ([[temp.explicit]]) or explicitly
50
- specialized ([[temp.expl.spec]]).
51
-
52
- Default and copy/move constructors may be implicitly declared as
53
- specified in  [[class.ctor]] and  [[class.copy]].
54
-
55
- ``` cpp
56
- struct B1 {
57
- B1(int);
58
- };
59
-
60
- struct B2 {
61
- B2(int = 13, int = 42);
62
- };
63
-
64
- struct D1 : B1 {
65
- using B1::B1;
66
- };
67
-
68
- struct D2 : B2 {
69
- using B2::B2;
70
- };
71
- ```
72
-
73
- The candidate set of inherited constructors in `D1` for `B1` is
74
-
75
- - `B1(const B1&)`
76
- - `B1(B1&&)`
77
- - `B1(int)`
78
-
79
- The set of constructors present in `D1` is
80
-
81
- - `D1()`, implicitly-declared default constructor, ill-formed if
82
- odr-used
83
- - `D1(const D1&)`, implicitly-declared copy constructor, not inherited
84
- - `D1(D1&&)`, implicitly-declared move constructor, not inherited
85
- - `D1(int)`, implicitly-declared inheriting constructor
86
-
87
- The candidate set of inherited constructors in `D2` for `B2` is
88
-
89
- - `B2(const B2&)`
90
- - `B2(B2&&)`
91
- - `B2(int = 13, int = 42)`
92
- - `B2(int = 13)`
93
- - `B2()`
94
-
95
- The set of constructors present in `D2` is
96
-
97
- - `D2()`, implicitly-declared default constructor, not inherited
98
- - `D2(const D2&)`, implicitly-declared copy constructor, not inherited
99
- - `D2(D2&&)`, implicitly-declared move constructor, not inherited
100
- - `D2(int, int)`, implicitly-declared inheriting constructor
101
- - `D2(int)`, implicitly-declared inheriting constructor
102
-
103
- If two *using-declaration*s declare inheriting constructors with the
104
- same signatures, the program is ill-formed ([[class.mem]],
105
- [[over.load]]), because an implicitly-declared constructor introduced by
106
- the first *using-declaration* is not a user-declared constructor and
107
- thus does not preclude another declaration of a constructor with the
108
- same signature by a subsequent *using-declaration*.
109
-
110
- ``` cpp
111
- struct B1 {
112
- B1(int);
113
- };
114
-
115
- struct B2 {
116
- B2(int);
117
- };
118
-
119
- struct D1 : B1, B2 {
120
- using B1::B1;
121
- using B2::B2;
122
- }; // ill-formed: attempts to declare D1(int) twice
123
-
124
- struct D2 : B1, B2 {
125
- using B1::B1;
126
- using B2::B2;
127
- D2(int); // OK: user declaration supersedes both implicit declarations
128
- };
129
- ```
130
-
131
- An inheriting constructor for a class is implicitly defined when it is
132
- odr-used ([[basic.def.odr]]) to create an object of its class type (
133
- [[intro.object]]). An implicitly-defined inheriting constructor performs
134
- the set of initializations of the class that would be performed by a
135
- user-written `inline` constructor for that class with a
136
- *mem-initializer-list* whose only *mem-initializer* has a
137
- *mem-initializer-id* that names the base class denoted in the
138
- *nested-name-specifier* of the *using-declaration* and an
139
- *expression-list* as specified below, and where the *compound-statement*
140
- in its function body is empty ([[class.base.init]]). If that
141
- user-written constructor would be ill-formed, the program is ill-formed.
142
- Each *expression* in the *expression-list* is of the form
143
- `static_cast<T&&>(p)`, where `p` is the name of the corresponding
144
- constructor parameter and `T` is the declared type of `p`.
145
-
146
- ``` cpp
147
- struct B1 {
148
- B1(int) { }
149
- };
150
-
151
- struct B2 {
152
- B2(double) { }
153
- };
154
-
155
- struct D1 : B1 {
156
- using B1::B1; // implicitly declares D1(int)
157
- int x;
158
- };
159
-
160
- void test() {
161
- D1 d(6); // OK: d.x is not initialized
162
- D1 e; // error: D1 has no default constructor
163
- }
164
-
165
- struct D2 : B2 {
166
- using B2::B2; // OK: implicitly declares D2(double)
167
- B1 b;
168
- };
169
-
170
- D2 f(1.0); // error: B1 has no default constructor
171
-
172
- template< class T >
173
- struct D : T {
174
- using T::T; // declares all constructors from class T
175
- ~D() { std::clog << "Destroying wrapper" << std::endl; }
176
- };
177
- ```
178
-
179
- Class template `D` wraps any class and forwards all of its constructors,
180
- while writing a message to the standard log whenever an object of class
181
- `D` is destroyed.
182
-
183
- <!-- Link reference definitions -->
184
- [basic.def.odr]: basic.md#basic.def.odr
185
- [basic.life]: basic.md#basic.life
186
- [basic.lookup]: basic.md#basic.lookup
187
- [basic.lval]: basic.md#basic.lval
188
- [basic.start.init]: basic.md#basic.start.init
189
- [basic.start.term]: basic.md#basic.start.term
190
- [basic.stc]: basic.md#basic.stc
191
- [basic.stc.auto]: basic.md#basic.stc.auto
192
- [basic.stc.dynamic]: basic.md#basic.stc.dynamic
193
- [basic.stc.dynamic.deallocation]: basic.md#basic.stc.dynamic.deallocation
194
- [basic.stc.static]: basic.md#basic.stc.static
195
- [basic.stc.thread]: basic.md#basic.stc.thread
196
- [basic.types]: basic.md#basic.types
197
- [class]: class.md#class
198
- [class.abstract]: class.md#class.abstract
199
- [class.access]: class.md#class.access
200
- [class.base.init]: #class.base.init
201
- [class.cdtor]: #class.cdtor
202
- [class.conv]: #class.conv
203
- [class.conv.ctor]: #class.conv.ctor
204
- [class.conv.fct]: #class.conv.fct
205
- [class.copy]: #class.copy
206
- [class.ctor]: #class.ctor
207
- [class.dtor]: #class.dtor
208
- [class.expl.init]: #class.expl.init
209
- [class.free]: #class.free
210
- [class.friend]: class.md#class.friend
211
- [class.inhctor]: #class.inhctor
212
- [class.init]: #class.init
213
- [class.mem]: class.md#class.mem
214
- [class.member.lookup]: class.md#class.member.lookup
215
- [class.mfct]: class.md#class.mfct
216
- [class.mi]: class.md#class.mi
217
- [class.qual]: basic.md#class.qual
218
- [class.temporary]: #class.temporary
219
- [class.union]: class.md#class.union
220
- [class.virtual]: class.md#class.virtual
221
- [conv]: conv.md#conv
222
- [conv.lval]: conv.md#conv.lval
223
- [dcl.array]: dcl.md#dcl.array
224
- [dcl.constexpr]: dcl.md#dcl.constexpr
225
- [dcl.fct]: dcl.md#dcl.fct
226
- [dcl.fct.def]: dcl.md#dcl.fct.def
227
- [dcl.fct.def.delete]: dcl.md#dcl.fct.def.delete
228
- [dcl.fct.default]: dcl.md#dcl.fct.default
229
- [dcl.fct.spec]: dcl.md#dcl.fct.spec
230
- [dcl.init]: dcl.md#dcl.init
231
- [dcl.init.aggr]: dcl.md#dcl.init.aggr
232
- [dcl.init.list]: dcl.md#dcl.init.list
233
- [dcl.init.ref]: dcl.md#dcl.init.ref
234
- [dcl.type.cv]: dcl.md#dcl.type.cv
235
- [diff.special]: compatibility.md#diff.special
236
- [except]: except.md#except
237
- [except.ctor]: except.md#except.ctor
238
- [except.spec]: except.md#except.spec
239
- [except.throw]: except.md#except.throw
240
- [expr]: expr.md#expr
241
- [expr.ass]: expr.md#expr.ass
242
- [expr.call]: expr.md#expr.call
243
- [expr.cast]: expr.md#expr.cast
244
- [expr.const.cast]: expr.md#expr.const.cast
245
- [expr.delete]: expr.md#expr.delete
246
- [expr.dynamic.cast]: expr.md#expr.dynamic.cast
247
- [expr.new]: expr.md#expr.new
248
- [expr.prim]: expr.md#expr.prim
249
- [expr.pseudo]: expr.md#expr.pseudo
250
- [expr.ref]: expr.md#expr.ref
251
- [expr.static.cast]: expr.md#expr.static.cast
252
- [expr.type.conv]: expr.md#expr.type.conv
253
- [expr.typeid]: expr.md#expr.typeid
254
- [expr.unary.op]: expr.md#expr.unary.op
255
- [intro.execution]: intro.md#intro.execution
256
- [intro.object]: intro.md#intro.object
257
- [namespace.udecl]: dcl.md#namespace.udecl
258
- [over.ass]: over.md#over.ass
259
- [over.best.ics]: over.md#over.best.ics
260
- [over.ics.ref]: over.md#over.ics.ref
261
- [over.load]: over.md#over.load
262
- [over.match]: over.md#over.match
263
- [over.match.best]: over.md#over.match.best
264
- [over.over]: over.md#over.over
265
- [special]: #special
266
- [stmt.dcl]: stmt.md#stmt.dcl
267
- [stmt.return]: stmt.md#stmt.return
268
- [temp.dep.type]: temp.md#temp.dep.type
269
- [temp.expl.spec]: temp.md#temp.expl.spec
270
- [temp.explicit]: temp.md#temp.explicit
271
- [temp.over.link]: temp.md#temp.over.link
272
- [temp.param]: temp.md#temp.param
273
- [temp.variadic]: temp.md#temp.variadic
274
-
275
- [^1]: The same rules apply to initialization of an `initializer_list`
276
- object ([[dcl.init.list]]) with its underlying temporary array
277
-
278
- [^2]: These conversions are considered as standard conversions for the
279
- purposes of overload resolution ([[over.best.ics]],
280
- [[over.ics.ref]]) and therefore initialization ([[dcl.init]]) and
281
- explicit casts ([[expr.static.cast]]). A conversion to `void` does
282
- not invoke any conversion function ([[expr.static.cast]]). Even
283
- though never directly called to perform a conversion, such
284
- conversion functions can be declared and can potentially be reached
285
- through a call to a virtual conversion function in a base class.
286
-
287
- [^3]: A similar provision is not needed for the array version of
288
- `operator` `delete` because  [[expr.delete]] requires that in this
289
- situation, the static type of the object to be deleted be the same
290
- as its dynamic type.
291
-
292
- [^4]: This implies that the reference parameter of the
293
- implicitly-declared copy constructor cannot bind to a `volatile`
294
- lvalue; see  [[diff.special]].
295
-
296
- [^5]: Because a template assignment operator or an assignment operator
297
- taking an rvalue reference parameter is never a copy assignment
298
- operator, the presence of such an assignment operator does not
299
- suppress the implicit declaration of a copy assignment operator.
300
- Such assignment operators participate in overload resolution with
301
- other assignment operators, including copy assignment operators,
302
- and, if selected, will be used to assign an object.
303
-
304
- [^6]: This implies that the reference parameter of the
305
- implicitly-declared copy assignment operator cannot bind to a
306
- `volatile` lvalue; see  [[diff.special]].
307
-
308
- [^7]: Because only one object is destroyed instead of two, and one
309
- copy/move constructor is not executed, there is still one object
310
- destroyed for each one constructed.