Files
cppdraft_translate/cppdraft/class/mem.md
2025-10-25 03:02:53 +03:00

2817 lines
139 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[class.mem]
# 11 Classes [[class]](./#class)
## 11.4 Class members [class.mem]
### [11.4.1](#general) General [[class.mem.general]](class.mem.general)
[member-specification:](#nt:member-specification "11.4.1General[class.mem.general]")
[*member-declaration*](#nt:member-declaration "11.4.1General[class.mem.general]") [*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]")opt
[*access-specifier*](class.derived.general#nt:access-specifier "11.7.1General[class.derived.general]") : [*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]")opt
[member-declaration:](#nt:member-declaration "11.4.1General[class.mem.general]")
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]")opt [*member-declarator-list*](#nt:member-declarator-list "11.4.1General[class.mem.general]")opt ;
[*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1General[dcl.fct.def.general]")
[*friend-type-declaration*](#nt:friend-type-declaration "11.4.1General[class.mem.general]")
[*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")
[*using-enum-declaration*](enum.udecl#nt:using-enum-declaration "9.8.2The using enum declaration[enum.udecl]")
[*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1Preamble[dcl.pre]")
[*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1Preamble[dcl.pre]")
[*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]")
[*explicit-specialization*](temp.expl.spec#nt:explicit-specialization "13.9.4Explicit specialization[temp.expl.spec]")
[*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3Deduction guides[temp.deduct.guide]")
[*alias-declaration*](dcl.pre#nt:alias-declaration "9.1Preamble[dcl.pre]")
[*opaque-enum-declaration*](dcl.enum#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]")
[*empty-declaration*](dcl.pre#nt:empty-declaration "9.1Preamble[dcl.pre]")
[member-declarator-list:](#nt:member-declarator-list "11.4.1General[class.mem.general]")
[*member-declarator*](#nt:member-declarator "11.4.1General[class.mem.general]")
[*member-declarator-list*](#nt:member-declarator-list "11.4.1General[class.mem.general]") , [*member-declarator*](#nt:member-declarator "11.4.1General[class.mem.general]")
[member-declarator:](#nt:member-declarator "11.4.1General[class.mem.general]")
[*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") [*virt-specifier-seq*](#nt:virt-specifier-seq "11.4.1General[class.mem.general]")opt [*function-contract-specifier-seq*](dcl.contract.func#nt:function-contract-specifier-seq "9.4.1General[dcl.contract.func]")opt [*pure-specifier*](#nt:pure-specifier "11.4.1General[class.mem.general]")opt
[*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]") [*function-contract-specifier-seq*](dcl.contract.func#nt:function-contract-specifier-seq "9.4.1General[dcl.contract.func]")opt
[*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt : [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")opt
[virt-specifier-seq:](#nt:virt-specifier-seq "11.4.1General[class.mem.general]")
[*virt-specifier*](#nt:virt-specifier "11.4.1General[class.mem.general]") [*virt-specifier-seq*](#nt:virt-specifier-seq "11.4.1General[class.mem.general]")opt
[virt-specifier:](#nt:virt-specifier "11.4.1General[class.mem.general]")
override
final
[pure-specifier:](#nt:pure-specifier "11.4.1General[class.mem.general]")
= 0
[friend-type-declaration:](#nt:friend-type-declaration "11.4.1General[class.mem.general]")
friend [*friend-type-specifier-list*](#nt:friend-type-specifier-list "11.4.1General[class.mem.general]") ;
[friend-type-specifier-list:](#nt:friend-type-specifier-list "11.4.1General[class.mem.general]")
[*friend-type-specifier*](#nt:friend-type-specifier "11.4.1General[class.mem.general]") ...opt
[*friend-type-specifier-list*](#nt:friend-type-specifier-list "11.4.1General[class.mem.general]") , [*friend-type-specifier*](#nt:friend-type-specifier "11.4.1General[class.mem.general]") ...opt
[friend-type-specifier:](#nt:friend-type-specifier "11.4.1General[class.mem.general]")
[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]")
[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]")
[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]")
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L616)
In the absence of a [*virt-specifier-seq*](#nt:virt-specifier-seq "11.4.1General[class.mem.general]"),
the token sequence = 0 is treated as a [*pure-specifier*](#nt:pure-specifier "11.4.1General[class.mem.general]") if the type of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") ([[dcl.meaning.general]](dcl.meaning.general "9.3.4.1General"))
is a function type, and
is otherwise treated as a [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")[.](#general-1.sentence-1)
[*Note [1](#general-note-1)*:
If the member declaration acquires a function type through
template instantiation,
the program is ill-formed; see [[temp.spec.general]](temp.spec.general "13.9.1General")[.](#general-1.sentence-2)
— *end note*]
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L628)
The optional [*function-contract-specifier-seq*](dcl.contract.func#nt:function-contract-specifier-seq "9.4.1General[dcl.contract.func]") ([[dcl.contract.func]](dcl.contract.func "9.4.1General"))
in a [*member-declarator*](#nt:member-declarator "11.4.1General[class.mem.general]") shall be present only if
the [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") declares a function[.](#general-2.sentence-1)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L634)
The [*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]") in a class definition declares the
full set of members of the class; no member can be added elsewhere[.](#general-3.sentence-1)
A [*direct member*](#def:member,direct "11.4.1General[class.mem.general]") of a class X is a member of X that was first declared within the [*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]") of X,
including anonymous union members ([[class.union.anon]](class.union.anon "11.5.2Anonymous unions")) and direct members thereof[.](#general-3.sentence-2)
Members of a class are data members, member
functions ([[class.mfct]](#class.mfct "11.4.2Member functions")), nested types, enumerators,
and member templates ([[temp.mem]](temp.mem "13.7.3Member templates")) and specializations thereof[.](#general-3.sentence-3)
[*Note [2](#general-note-2)*:
A specialization of a static data member template is a static data member[.](#general-3.sentence-4)
A specialization of a member function template is a member function[.](#general-3.sentence-5)
A specialization of a member class template is a nested class[.](#general-3.sentence-6)
— *end note*]
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L650)
A [*member-declaration*](#nt:member-declaration "11.4.1General[class.mem.general]") does not itself declare new members of the class
if it is
- [(4.1)](#general-4.1)
a friend declaration ([[class.friend]](class.friend "11.8.4Friends")),
- [(4.2)](#general-4.2)
a [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3Deduction guides[temp.deduct.guide]") ([[temp.deduct.guide]](temp.deduct.guide "13.7.2.3Deduction guides")),
- [(4.3)](#general-4.3)
a [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]") whose [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") is one of the above,
- [(4.4)](#general-4.4)
a [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1Preamble[dcl.pre]"),
- [(4.5)](#general-4.5)
a [*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1Preamble[dcl.pre]"),
- [(4.6)](#general-4.6)
a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration")), or
- [(4.7)](#general-4.7)
an [*empty-declaration*](dcl.pre#nt:empty-declaration "9.1Preamble[dcl.pre]")[.](#general-4.sentence-1)
For any other [*member-declaration*](#nt:member-declaration "11.4.1General[class.mem.general]"),
each declared entity
that is not an [unnamed bit-field](#def:bit-field,unnamed "11.4.10Bit-fields[class.bit]") is a member of the class,
and each such [*member-declaration*](#nt:member-declaration "11.4.1General[class.mem.general]") shall either
declare at least one member name of the class
or declare at least one unnamed bit-field[.](#general-4.sentence-2)
[5](#general-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L671)
A [*data member*](#def:data_member "11.4.1General[class.mem.general]") is a non-function member introduced by a[*member-declarator*](#nt:member-declarator "11.4.1General[class.mem.general]")[.](#general-5.sentence-1)
A [*member function*](#def:member_function "11.4.1General[class.mem.general]") is a member that is a function[.](#general-5.sentence-2)
Nested types are classes ([[class.name]](class.name "11.3Class names"), [[class.nest]](#class.nest "11.4.12Nested class declarations")) and
enumerations ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")) declared in the class and arbitrary types
declared as members by use of a typedef declaration ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier"))
or [*alias-declaration*](dcl.pre#nt:alias-declaration "9.1Preamble[dcl.pre]")[.](#general-5.sentence-3)
The enumerators of an [unscoped enumeration](dcl.enum "9.8.1Enumeration declarations[dcl.enum]") defined in the class
are members of the class[.](#general-5.sentence-4)
[6](#general-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L682)
A data member or member function
may be declared static in its [*member-declaration*](#nt:member-declaration "11.4.1General[class.mem.general]"),
in which case it is a [*static member*](#def:member,static "11.4.1General[class.mem.general]") (see [[class.static]](#class.static "11.4.9Static members"))
(a [*static data member*](#def:data_member,static "11.4.1General[class.mem.general]") ([[class.static.data]](#class.static.data "11.4.9.3Static data members")) or[*static member function*](#def:member_function,static "11.4.1General[class.mem.general]") ([[class.static.mfct]](#class.static.mfct "11.4.9.2Static member functions")), respectively)
of the class[.](#general-6.sentence-1)
Any other data member or member function is a [*non-static member*](#def:member,non-static "11.4.1General[class.mem.general]") (a [*non-static data member*](#def:data_member,non-static "11.4.1General[class.mem.general]") or[*non-static member function*](#def:member_function,non-static "11.4.1General[class.mem.general]") ([[class.mfct.non.static]](#class.mfct.non.static "11.4.3Non-static member functions")), respectively)[.](#general-6.sentence-2)
[7](#general-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L693)
Every object of class type has a unique member subobject
corresponding to each of its direct non-static data members[.](#general-7.sentence-1)
If any non-static data member of a class C is of reference type,
then let D be an invented class
that is identical to C except that each non-static member of D corresponding to
a member of C of type “reference to T”
instead has type “pointer to T”[.](#general-7.sentence-2)
Every member subobject of a complete object of type C has the same size, alignment, and offset
as that of the corresponding subobject of a complete object of type D[.](#general-7.sentence-3)
The size and alignment of C are the same as
the size and alignment of D[.](#general-7.sentence-4)
[8](#general-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L708)
A member shall not be declared twice in the[*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]"), except that
- [(8.1)](#general-8.1)
a nested class or member
class template can be declared and then later defined, and
- [(8.2)](#general-8.2)
an
enumeration can be introduced with an [*opaque-enum-declaration*](dcl.enum#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]") and later
redeclared with an [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]")[.](#general-8.sentence-1)
[*Note [3](#general-note-3)*:
A single name can denote several member functions provided their types
are sufficiently different ([[basic.scope.scope]](basic.scope.scope "6.4.1General"))[.](#general-8.sentence-2)
— *end note*]
[9](#general-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L723)
A redeclaration of a class member outside its class definition shall be
a definition,
an explicit specialization, or
an explicit instantiation ([[temp.expl.spec]](temp.expl.spec "13.9.4Explicit specialization"), [[temp.explicit]](temp.explicit "13.9.3Explicit instantiation"))[.](#general-9.sentence-1)
The member shall not be a non-static data member[.](#general-9.sentence-2)
[10](#general-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L730)
A [*complete-class context*](#def:complete-class_context "11.4.1General[class.mem.general]") of a class (template) is a
- [(10.1)](#general-10.1)
function body ([[dcl.fct.def.general]](dcl.fct.def.general "9.6.1General")),
- [(10.2)](#general-10.2)
default argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments")),
- [(10.3)](#general-10.3)
default template argument ([[temp.param]](temp.param "13.2Template parameters")),
- [(10.4)](#general-10.4)
[*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5Exception specifications[except.spec]") ([[except.spec]](except.spec "14.5Exception specifications")),
- [(10.5)](#general-10.5)
[*function-contract-specifier*](dcl.contract.func#nt:function-contract-specifier "9.4.1General[dcl.contract.func]") ([[dcl.contract.func]](dcl.contract.func "9.4.1General")), or
- [(10.6)](#general-10.6)
default member initializer
within the [*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]") of the class or class template[.](#general-10.sentence-1)
[*Note [4](#general-note-4)*:
A complete-class context of a nested class is also a complete-class
context of any enclosing class, if the nested class is defined within
the [*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]") of the enclosing class[.](#general-10.sentence-2)
— *end note*]
[11](#general-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L748)
A class C is complete at a program point P if the definition of C is reachable from P ([[module.reach]](module.reach "10.7Reachability"))
or if P is in a complete-class context of C[.](#general-11.sentence-1)
Otherwise, C is incomplete at P[.](#general-11.sentence-2)
[12](#general-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L754)
If a [*member-declaration*](#nt:member-declaration "11.4.1General[class.mem.general]") matches
the syntactic requirements of [*friend-type-declaration*](#nt:friend-type-declaration "11.4.1General[class.mem.general]"),
it is a [*friend-type-declaration*](#nt:friend-type-declaration "11.4.1General[class.mem.general]")[.](#general-12.sentence-1)
[13](#general-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L759)
In a [*member-declarator*](#nt:member-declarator "11.4.1General[class.mem.general]"),
an = immediately following the [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") is interpreted as introducing a [*pure-specifier*](#nt:pure-specifier "11.4.1General[class.mem.general]") if the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") has function type,
otherwise it is interpreted as introducing
a [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")[.](#general-13.sentence-1)
[*Example [1](#general-example-1)*: struct S {using T = void();
T * p = 0; // OK, [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")virtual T f = 0; // OK, [*pure-specifier*](#nt:pure-specifier "11.4.1General[class.mem.general]")}; — *end example*]
[14](#general-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L776)
In a [*member-declarator*](#nt:member-declarator "11.4.1General[class.mem.general]") for a bit-field,
the [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") is parsed as
the longest sequence of tokens
that could syntactically form a [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]")[.](#general-14.sentence-1)
[*Example [2](#general-example-2)*: int a;const int b = 0;struct S {int x1 : 8 = 42; // OK, "= 42" is [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")int x2 : 8 { 42 }; // OK, "{ 42 }" is [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")int y1 : true ? 8 : a = 42; // OK, [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]") is absentint y2 : true ? 8 : b = 42; // error: cannot assign to const intint y3 : (true ? 8 : b) = 42; // OK, "= 42" is [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")int z : 1 || new int { 0 }; // OK, [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]") is absent}; — *end example*]
[15](#general-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L796)
A [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]") shall appear only in the
declaration of a data member[.](#general-15.sentence-1)
(For static data members,
see [[class.static.data]](#class.static.data "11.4.9.3Static data members"); for non-static data members,
see [[class.base.init]](class.base.init "11.9.3Initializing bases and members") and [[dcl.init.aggr]](dcl.init.aggr "9.5.2Aggregates"))[.](#general-15.sentence-2)
A [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]") for a non-static data memberspecifies a [*default member initializer*](#def:default_member_initializer "11.4.1General[class.mem.general]") for the member, and
shall not directly or indirectly cause the implicit definition of a
defaulted default constructor for the enclosing class or the
exception specification of that constructor[.](#general-15.sentence-3)
An immediate invocation ([[expr.const]](expr.const "7.7Constant expressions")) that
is a potentially-evaluated subexpression ([[intro.execution]](intro.execution "6.10.1Sequential execution"))
of a default member initializer
is neither evaluated nor checked for whether it
is a constant expression at the point where the subexpression appears[.](#general-15.sentence-4)
[16](#general-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L813)
A member shall not be declared with the extern[*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2Storage class specifiers[dcl.stc]")[.](#general-16.sentence-1)
Within a class definition, a member shall not be declared with the thread_local [*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2Storage class specifiers[dcl.stc]") unless also declared static[.](#general-16.sentence-2)
[17](#general-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L817)
The [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") may be omitted in constructor, destructor,
and conversion function declarations only;
when declaring another kind of member the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") shall contain a [*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1General[dcl.type.general]") that is not a [*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1General[dcl.decl.general]")[.](#general-17.sentence-1)
The[*member-declarator-list*](#nt:member-declarator-list "11.4.1General[class.mem.general]") can be omitted only after a[*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") or an [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]") or in a[friend declaration](class.friend "11.8.4Friends[class.friend]")[.](#general-17.sentence-2)
A[*pure-specifier*](#nt:pure-specifier "11.4.1General[class.mem.general]") shall be used only in the declaration of a[virtual function](class.virtual "11.7.3Virtual functions[class.virtual]") that is not a friend declaration[.](#general-17.sentence-3)
[18](#general-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L830)
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") in a [*member-declaration*](#nt:member-declaration "11.4.1General[class.mem.general]") appertains to each of the entities declared by the [*member-declarator*](#nt:member-declarator "11.4.1General[class.mem.general]")*s*;
it shall not appear if the optional [*member-declarator-list*](#nt:member-declarator-list "11.4.1General[class.mem.general]") is omitted[.](#general-18.sentence-1)
[19](#general-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L835)
A [*virt-specifier-seq*](#nt:virt-specifier-seq "11.4.1General[class.mem.general]") shall contain at most one of each[*virt-specifier*](#nt:virt-specifier "11.4.1General[class.mem.general]")[.](#general-19.sentence-1)
A [*virt-specifier-seq*](#nt:virt-specifier-seq "11.4.1General[class.mem.general]") shall appear only in the first declaration of a virtual member
function ([[class.virtual]](class.virtual "11.7.3Virtual functions"))[.](#general-19.sentence-2)
[20](#general-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L842)
The type of a non-static data member shall not be an
incomplete type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1General")),
an abstract class type ([[class.abstract]](class.abstract "11.7.4Abstract classes")),
or a (possibly multidimensional) array thereof[.](#general-20.sentence-1)
[*Note [5](#general-note-5)*:
In particular, a class C cannot contain
a non-static member of class C,
but it can contain a pointer or reference to an object of class C[.](#general-20.sentence-2)
— *end note*]
[21](#general-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L854)
[*Note [6](#general-note-6)*:
See [[expr.prim.id]](expr.prim.id "7.5.5Names") for restrictions on the use of non-static data
members and non-static member functions[.](#general-21.sentence-1)
— *end note*]
[22](#general-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L860)
[*Note [7](#general-note-7)*:
The type of a non-static member function is an ordinary function type,
and the type of a non-static data member is an ordinary object type[.](#general-22.sentence-1)
There are no special member function types or data member types[.](#general-22.sentence-2)
— *end note*]
[23](#general-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L867)
[*Example [3](#general-example-3)*:
A simple example of a class definition isstruct tnode {char tword[20]; int count;
tnode* left;
tnode* right;}; which contains an array of twenty characters, an integer, and two
pointers to objects of the same type[.](#general-23.sentence-1)
Once this definition has been
given, the declarationtnode s, *sp; declares s to be a tnode and sp to be a pointer
to a tnode[.](#general-23.sentence-2)
With these declarations, sp->count refers to
the count member of the object to which sp points;s.left refers to the left subtree pointer of the objects; and s.right->tword[0] refers to the initial character
of the tword member of the right subtree of s[.](#general-23.sentence-3)
— *end example*]
[24](#general-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L892)
[*Note [8](#general-note-8)*:
Non-variant non-static data members of
non-zero size ([[intro.object]](intro.object "6.8.2Object model"))
are allocated so that later
members have higher addresses within a class object ([[expr.rel]](expr.rel "7.6.9Relational operators"))[.](#general-24.sentence-1)
Implementation alignment requirements can cause two adjacent members
not to be allocated immediately after each other; so can requirements
for space for managing virtual functions ([[class.virtual]](class.virtual "11.7.3Virtual functions")) and
virtual base classes ([[class.mi]](class.mi "11.7.2Multiple base classes"))[.](#general-24.sentence-2)
— *end note*]
[25](#general-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L905)
If T is the name of a class, then each of the following shall
have a name different from T:
- [(25.1)](#general-25.1)
every static data member of class T;
- [(25.2)](#general-25.2)
every member function of class T;
[*Note [9](#general-note-9)*:
This restriction does not apply to constructors, which do not have
names ([[class.ctor]](#class.ctor "11.4.5Constructors"))[.](#general-25.2.sentence-1)
— *end note*]
- [(25.3)](#general-25.3)
every member of class T that is itself a type;
- [(25.4)](#general-25.4)
every member template of class T;
- [(25.5)](#general-25.5)
every enumerator of every member of class T that is an
unscoped enumeration type; and
- [(25.6)](#general-25.6)
every member of every anonymous union that is a member of classT[.](#general-25.sentence-1)
[26](#general-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L928)
In addition, if class T has a user-declared[constructor](#class.ctor "11.4.5Constructors[class.ctor]"), every non-static data member of classT shall have a name different from T[.](#general-26.sentence-1)
[27](#general-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L933)
The [*common initial sequence*](#def:common_initial_sequence "11.4.1General[class.mem.general]") of two standard-layout struct ([[class.prop]](class.prop "11.2Properties of classes"))
types is the longest sequence of non-static data
members and bit-fields in declaration order, starting with the first
such entity in each of the structs, such that
- [(27.1)](#general-27.1)
corresponding entities
have layout-compatible types ([[basic.types]](basic.types "6.9Types")),
- [(27.2)](#general-27.2)
corresponding entities have the same alignment requirements ([[basic.align]](basic.align "6.8.3Alignment")),
- [(27.3)](#general-27.3)
if a [*has-attribute-expression*](cpp.cond#nt:has-attribute-expression "15.2Conditional inclusion[cpp.cond]") ([[cpp.cond]](cpp.cond "15.2Conditional inclusion"))
is not 0 for the no_unique_address attribute,
then neither entity is declared with
the no_unique_address attribute ([[dcl.attr.nouniqueaddr]](dcl.attr.nouniqueaddr "9.13.11No unique address attribute")), and
- [(27.4)](#general-27.4)
either both entities are bit-fields with the same width
or neither is a bit-field[.](#general-27.sentence-1)
[*Example [4](#general-example-4)*: struct A { int a; char b; };struct B { const int b1; volatile char b2; };struct C { int c; unsigned : 0; char b; };struct D { int d; char b : 4; };struct E { unsigned int e; char b; };
The common initial sequence of A and B comprises all members
of either class[.](#general-27.sentence-2)
The common initial sequence of A and C and
of A and D comprises the first member in each case[.](#general-27.sentence-3)
The common initial sequence of A and E is empty[.](#general-27.sentence-4)
— *end example*]
[28](#general-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L967)
Two standard-layout struct ([[class.prop]](class.prop "11.2Properties of classes")) types are[*layout-compatible classes*](#def:layout-compatible,class "11.4.1General[class.mem.general]") if
their common initial sequence comprises all members and bit-fields of
both classes ([[basic.types]](basic.types "6.9Types"))[.](#general-28.sentence-1)
[29](#general-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L973)
Two standard-layout unions are layout-compatible if they
have the same number of non-static data members and corresponding
non-static data members (in any order) have layout-compatible
types ([[basic.types.general]](basic.types.general#term.layout.compatible.type "6.9.1General"))[.](#general-29.sentence-1)
[30](#general-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L979)
In a standard-layout union with an [active member](class.union#def:active,union_member "11.5Unions[class.union]") of struct type T1, it is permitted to read a non-static
data member m of another union member of struct type T2 provided m is part of the common initial sequence of T1 and T2;
the behavior is as if the corresponding member of T1 were nominated[.](#general-30.sentence-1)
[*Example [5](#general-example-5)*: struct T1 { int a, b; };struct T2 { int c; double d; };union U { T1 t1; T2 t2; };int f() { U u = { { 1, 2 } }; // active member is t1return u.t2.c; // OK, as if u.t1.a were nominated} — *end example*]
[*Note [10](#general-note-10)*:
Reading a volatile object through a glvalue of non-volatile type has
undefined behavior ([[dcl.type.cv]](dcl.type.cv "9.2.9.2The cv-qualifiers"))[.](#general-30.sentence-2)
— *end note*]
[31](#general-31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1001)
If a standard-layout class object has any non-static data members, its address
is the same as the address of its first non-static data member
if that member is not a bit-field[.](#general-31.sentence-1)
Its
address is also the same as the address of each of its base class subobjects[.](#general-31.sentence-2)
[*Note [11](#general-note-11)*:
There can therefore be unnamed padding within a standard-layout struct object
inserted by an implementation, but
not at its beginning, as necessary to achieve appropriate alignment[.](#general-31.sentence-3)
— *end note*]
[*Note [12](#general-note-12)*:
The object and its first subobject are
pointer-interconvertible ([[basic.compound]](basic.compound "6.9.4Compound types"), [[expr.static.cast]](expr.static.cast "7.6.1.9Static cast"))[.](#general-31.sentence-4)
— *end note*]
[32](#general-32)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1016)
A [*data member description*](#def:description,data_member "11.4.1General[class.mem.general]") is
a quintuple (T, N, A, W, NUA)
describing the potential declaration of a non-static data member where
- [(32.1)](#general-32.1)
T is a type,
- [(32.2)](#general-32.2)
N is an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") or ⊥,
- [(32.3)](#general-32.3)
A is an alignment or ⊥,
- [(32.4)](#general-32.4)
W is a bit-field width or ⊥, and
- [(32.5)](#general-32.5)
NUA is a boolean value[.](#general-32.sentence-1)
Two data member descriptions are equal
if each of their respective components are the same entities,
are the same identifiers, have equal values, or are both ⊥[.](#general-32.sentence-2)
[*Note [13](#general-note-13)*:
The components of a data member description describe a data member such that
- [(32.6)](#general-32.6)
its type is specified using the type given by T,
- [(32.7)](#general-32.7)
it is declared with the name given by N if N is not ⊥ and is otherwise unnamed,
- [(32.8)](#general-32.8)
it is declared with the [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") ([[dcl.align]](dcl.align "9.13.2Alignment specifier"))
given by alignas(A) if A is not ⊥ and
is otherwise declared without an [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1Attribute syntax and semantics[dcl.attr.grammar]"),
- [(32.9)](#general-32.9)
it is a bit-field ([[class.bit]](#class.bit "11.4.10Bit-fields")) with the width given by W if W is not ⊥ and is otherwise not a bit-field, and
- [(32.10)](#general-32.10)
it is declared with
the attribute [[no_unique_address]] ([[dcl.attr.nouniqueaddr]](dcl.attr.nouniqueaddr "9.13.11No unique address attribute"))
if NUA is true and is otherwise declared without that attribute[.](#general-32.sentence-3)
Data member descriptions are represented by reflections ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))
returned by std::meta::data_member_spec ([[meta.reflection.define.aggregate]](meta.reflection.define.aggregate "21.4.16Reflection class definition generation")) and
can be reified as data members of a class using std::meta::define_aggregate[.](#general-32.sentence-4)
— *end note*]
### [11.4.2](#class.mfct) Member functions [[class.mfct]](class.mfct)
[1](#class.mfct-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1059)
If a member function is attached to the global module and is defined ([[dcl.fct.def]](dcl.fct.def "9.6Function definitions")) in its class definition,
it is inline ([[dcl.inline]](dcl.inline "9.2.8The inline specifier"))[.](#class.mfct-1.sentence-1)
[*Note [1](#class.mfct-note-1)*:
A member function is also inline if it is declaredinline, constexpr, or consteval[.](#class.mfct-1.sentence-2)
— *end note*]
[2](#class.mfct-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1069)
[*Example [1](#class.mfct-example-1)*: struct X {typedef int T; static T count; void f(T);};void X::f(T t = count) { }
The definition of the member function f of class X inhabits the global
scope; the notation X::f indicates that the function f is a member of class X and in the scope of class X[.](#class.mfct-2.sentence-1)
In
the function definition, the parameter type T refers to the
typedef member T declared in class X and the default
argument count refers to the static data member count declared in class X[.](#class.mfct-2.sentence-2)
— *end example*]
[3](#class.mfct-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1090)
Member functions of a local class shall be defined inline in their class
definition, if they are defined at all[.](#class.mfct-3.sentence-1)
[4](#class.mfct-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1095)
[*Note [2](#class.mfct-note-2)*:
A member function can be declared (but not defined) using a typedef for
a function type[.](#class.mfct-4.sentence-1)
The resulting member function has exactly the same type
as it would have if the function declarator were provided explicitly,
see [[dcl.fct]](dcl.fct "9.3.4.6Functions") and [[temp.arg]](temp.arg "13.4Template arguments")[.](#class.mfct-4.sentence-2)
[*Example [2](#class.mfct-example-2)*: typedef void fv();typedef void fvc() const;struct S { fv memfunc1; // equivalent to: void memfunc1();void memfunc2();
fvc memfunc3; // equivalent to: void memfunc3() const;};
fv S::* pmfv1 = &S::memfunc1;
fv S::* pmfv2 = &S::memfunc2;
fvc S::* pmfv3 = &S::memfunc3; — *end example*]
— *end note*]
### [11.4.3](#class.mfct.non.static) Non-static member functions [[class.mfct.non.static]](class.mfct.non.static)
[1](#class.mfct.non.static-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1121)
A non-static member function may be called for an object of
its class type, or for an object of a class derived ([[class.derived]](class.derived "11.7Derived classes"))
from its class type, using the class member
access syntax ([[expr.ref]](expr.ref "7.6.1.5Class member access"), [[over.match.call]](over.match.call "12.2.2.2Function call syntax"))[.](#class.mfct.non.static-1.sentence-1)
A non-static
member function may also be called directly using the function call
syntax ([[expr.call]](expr.call "7.6.1.3Function call"), [[over.match.call]](over.match.call "12.2.2.2Function call syntax")) from within
its class or a class derived from its class, or
a member thereof, as described below[.](#class.mfct.non.static-1.sentence-2)
[2](#class.mfct.non.static-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1131)
[*Note [1](#class.mfct.non.static-note-1)*:
An implicit object member function can be declared with[*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1General[dcl.decl.general]")*s*, which affect the type of the this pointer ([[expr.prim.this]](expr.prim.this "7.5.3This")),
and/or a [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1General[dcl.decl.general]") ([[dcl.fct]](dcl.fct "9.3.4.6Functions"));
both affect overload resolution ([[over.match.funcs]](over.match.funcs "12.2.2Candidate functions and argument lists"))[.](#class.mfct.non.static-2.sentence-1)
— *end note*]
[3](#class.mfct.non.static-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1143)
An implicit object member function may be declared
virtual ([[class.virtual]](class.virtual "11.7.3Virtual functions")) or pure virtual ([[class.abstract]](class.abstract "11.7.4Abstract classes"))[.](#class.mfct.non.static-3.sentence-1)
### [11.4.4](#special) Special member functions [[special]](special)
[1](#special-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1154)
Default constructors ([[class.default.ctor]](#class.default.ctor "11.4.5.2Default constructors")),
copy constructors, move constructors ([[class.copy.ctor]](#class.copy.ctor "11.4.5.3Copy/move constructors")),
copy assignment operators, move assignment operators ([[class.copy.assign]](#class.copy.assign "11.4.6Copy/move assignment operator")),
and prospective destructors ([[class.dtor]](#class.dtor "11.4.7Destructors")) are[*special member functions*](#def:special_member_functions)[.](#special-1.sentence-1)
[*Note [1](#special-note-1)*:
The implementation will implicitly declare these member functions for some class
types when the program does not explicitly declare them[.](#special-1.sentence-2)
The implementation will implicitly define them
as needed ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2Explicitly-defaulted functions"))[.](#special-1.sentence-3)
— *end note*]
An implicitly-declared special member function is declared at the closing} of the [*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]")[.](#special-1.sentence-4)
Programs shall not define implicitly-declared special member functions[.](#special-1.sentence-5)
[2](#special-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1175)
Programs may explicitly refer to implicitly-declared special member functions[.](#special-2.sentence-1)
[*Example [1](#special-example-1)*:
A program may explicitly call or form a pointer to member
to an implicitly-declared special member function[.](#special-2.sentence-2)
struct A { }; // implicitly declared A::operator=struct B : A { B& operator=(const B &);};
B& B::operator=(const B& s) {this->A::operator=(s); // well-formedreturn *this;} — *end example*]
[3](#special-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1193)
[*Note [2](#special-note-2)*:
The special member functions affect the way objects of class type are created,
copied, moved, and destroyed, and how values can be converted to values of other types[.](#special-3.sentence-1)
Often such special member functions are called implicitly[.](#special-3.sentence-2)
— *end note*]
[4](#special-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1200)
Special member functions obey the usual access rules ([[class.access]](class.access "11.8Member access control"))[.](#special-4.sentence-1)
[*Example [2](#special-example-2)*:
Declaring a constructor protected
ensures that only derived classes and friends can create objects using it[.](#special-4.sentence-2)
— *end example*]
[5](#special-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1208)
Two special member functions are of the same kind if
- [(5.1)](#special-5.1)
they are both default constructors,
- [(5.2)](#special-5.2)
they are both copy or move constructors
with the same first parameter type, or
- [(5.3)](#special-5.3)
they are both copy or move assignment operators
with the same first parameter type
and the same [*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1General[dcl.decl.general]")*s* and [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1General[dcl.decl.general]"), if any[.](#special-5.sentence-1)
[6](#special-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1219)
An [*eligible special member function*](#def:special_member_function,eligible "11.4.4Special member functions[special]") is a special member function for which:
- [(6.1)](#special-6.1)
the function is not deleted,
- [(6.2)](#special-6.2)
the associated constraints ([[temp.constr]](temp.constr "13.5Template constraints")), if any, are satisfied, and
- [(6.3)](#special-6.3)
no special member function of the same kind
whose associated constraints, if any, are satisfied
is more constrained ([[temp.constr.order]](temp.constr.order "13.5.5Partial ordering by constraints"))[.](#special-6.sentence-1)
[7](#special-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1229)
For a class, its non-static data members, its non-virtual direct base classes,
and, if the class is not abstract ([[class.abstract]](class.abstract "11.7.4Abstract classes")), its virtual base
classes are called its [*potentially constructed subobjects*](#def:potentially_constructed_subobjects)[.](#special-7.sentence-1)
### [11.4.5](#class.ctor) Constructors [[class.ctor]](class.ctor)
#### [11.4.5.1](#class.ctor.general) General [[class.ctor.general]](class.ctor.general)
[1](#class.ctor.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1240)
A [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") declares a [*constructor*](#def:constructor "11.4.5.1General[class.ctor.general]") if it is a
function declarator ([[dcl.fct]](dcl.fct "9.3.4.6Functions")) of the form
[*ptr-declarator*](dcl.decl.general#nt:ptr-declarator "9.3.1General[dcl.decl.general]") ( [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6Functions[dcl.fct]") ) [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5Exception specifications[except.spec]")opt [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
where the [*ptr-declarator*](dcl.decl.general#nt:ptr-declarator "9.3.1General[dcl.decl.general]") consists solely of an[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]"), an optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]"),
and optional surrounding parentheses, and the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") has
one of the following forms:
- [(1.1)](#class.ctor.general-1.1)
in a friend declaration ([[class.friend]](class.friend "11.8.4Friends")),
the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") that names a constructor ([[class.qual]](class.qual "6.5.5.2Class members"));
- [(1.2)](#class.ctor.general-1.2)
otherwise, in a [*member-declaration*](#nt:member-declaration "11.4.1General[class.mem.general]") that belongs to the[*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]") of a class or class template,
the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") is the
injected-class-name ([[class.pre]](class.pre "11.1Preamble")) of the immediately-enclosing entity;
- [(1.3)](#class.ctor.general-1.3)
otherwise, the[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") whose [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") is
the injected-class-name of its lookup context[.](#class.ctor.general-1.sentence-1)
Constructors do not have names[.](#class.ctor.general-1.sentence-2)
In a constructor declaration, each [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1General[dcl.spec.general]") in the optional[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") shall befriend,inline,constexpr,consteval, or
an [*explicit-specifier*](dcl.fct.spec#nt:explicit-specifier "9.2.3Function specifiers[dcl.fct.spec]")[.](#class.ctor.general-1.sentence-3)
[*Example [1](#class.ctor.general-example-1)*: struct S { S(); // declares the constructor};
S::S() { } // defines the constructor — *end example*]
[2](#class.ctor.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1285)
A constructor is used to initialize objects of its class type[.](#class.ctor.general-2.sentence-1)
[*Note [1](#class.ctor.general-note-1)*:
Because constructors do not have names, they are never found during
unqualified name lookup; however an explicit type conversion using the functional
notation ([[expr.type.conv]](expr.type.conv "7.6.1.4Explicit type conversion (functional notation)")) will cause a constructor to be called to
initialize an object[.](#class.ctor.general-2.sentence-2)
The syntax looks like an explicit call of the constructor[.](#class.ctor.general-2.sentence-3)
— *end note*]
[*Example [2](#class.ctor.general-example-2)*: complex zz = complex(1,2.3);
cprint( complex(7.8,1.2) ); — *end example*]
[*Note [2](#class.ctor.general-note-2)*:
For initialization of objects of class type see [[class.init]](class.init "11.9Initialization")[.](#class.ctor.general-2.sentence-4)
— *end note*]
[3](#class.ctor.general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1305)
An object created in this way is unnamed[.](#class.ctor.general-3.sentence-1)
[*Note [3](#class.ctor.general-note-3)*:
[[class.temporary]](class.temporary "6.8.7Temporary objects") describes the lifetime of temporary objects[.](#class.ctor.general-3.sentence-2)
— *end note*]
[*Note [4](#class.ctor.general-note-4)*:
Explicit constructor calls do not yield lvalues, see [[basic.lval]](basic.lval "7.2.1Value category")[.](#class.ctor.general-3.sentence-3)
— *end note*]
[4](#class.ctor.general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1315)
[*Note [5](#class.ctor.general-note-5)*:
Some language constructs have special semantics when used during construction;
see [[class.base.init]](class.base.init "11.9.3Initializing bases and members") and [[class.cdtor]](class.cdtor "11.9.5Construction and destruction")[.](#class.ctor.general-4.sentence-1)
— *end note*]
[5](#class.ctor.general-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1322)
A constructor can be invoked for aconst,volatile orconstvolatile object[.](#class.ctor.general-5.sentence-1)
const andvolatile semantics ([[dcl.type.cv]](dcl.type.cv "9.2.9.2The cv-qualifiers")) are not applied on an object under construction[.](#class.ctor.general-5.sentence-2)
They come into effect when the constructor for the
most derived object ([[intro.object]](intro.object "6.8.2Object model")) ends[.](#class.ctor.general-5.sentence-3)
[6](#class.ctor.general-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1340)
The address of a constructor shall not be taken[.](#class.ctor.general-6.sentence-1)
[*Note [6](#class.ctor.general-note-6)*:
A return statement in the body of a constructor
cannot specify a return value ([[stmt.return]](stmt.return "8.8.4The return statement"))[.](#class.ctor.general-6.sentence-2)
— *end note*]
[7](#class.ctor.general-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1349)
A constructor shall not be a coroutine[.](#class.ctor.general-7.sentence-1)
[8](#class.ctor.general-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1352)
A constructor shall not have an explicit object parameter ([[dcl.fct]](dcl.fct "9.3.4.6Functions"))[.](#class.ctor.general-8.sentence-1)
#### [11.4.5.2](#class.default.ctor) Default constructors [[class.default.ctor]](class.default.ctor)
[1](#class.default.ctor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1357)
A [*default constructor*](#def:constructor,default "11.4.5.2Default constructors[class.default.ctor]") for a class X is a constructor of class X for which each parameter
that is not a function parameter pack
has a default argument
(including the case of a constructor with no parameters)[.](#class.default.ctor-1.sentence-1)
If there is no user-declared constructor or constructor template for classX,
a non-explicit constructor having no parameters is implicitly declared
as defaulted ([[dcl.fct.def]](dcl.fct.def "9.6Function definitions"))[.](#class.default.ctor-1.sentence-2)
An implicitly-declared default constructor is an
inline public member of its class[.](#class.default.ctor-1.sentence-3)
[2](#class.default.ctor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1374)
A defaulted default constructor for class X is defined as deleted if
- [(2.1)](#class.default.ctor-2.1)
any non-static data member with no default member initializer ([class.mem]) is
of reference type,
- [(2.2)](#class.default.ctor-2.2)
X is a non-union class and
any non-variant non-static data member of const-qualified type
(or possibly multidimensional array thereof)
with no [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]") is not const-default-constructible ([[dcl.init]](dcl.init "9.5Initializers")),
- [(2.3)](#class.default.ctor-2.3)
any non-variant potentially constructed subobject, except for a non-static data member
with a [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]"),
has class type M (or possibly multidimensional array thereof)
and overload resolution ([[over.match]](over.match "12.2Overload resolution"))
as applied to find M's corresponding constructor
does not result in a usable candidate ([[over.match.general]](over.match.general "12.2.1General")), or
- [(2.4)](#class.default.ctor-2.4)
any potentially constructed subobject S has
class type M (or possibly multidimensional array thereof),M has
a destructor that is deleted or inaccessible from the defaulted default
constructor, and
either S is non-variant or S has a default member initializer[.](#class.default.ctor-2.sentence-1)
[3](#class.default.ctor-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1401)
A default constructor for a class X is[*trivial*](#def:constructor,default,trivial "11.4.5.2Default constructors[class.default.ctor]") if it is not user-provided and if
- [(3.1)](#class.default.ctor-3.1)
X has no virtual functions ([[class.virtual]](class.virtual "11.7.3Virtual functions")) and no virtual base
classes ([[class.mi]](class.mi "11.7.2Multiple base classes")), and
- [(3.2)](#class.default.ctor-3.2)
no non-static data member of X has
a default member initializer ([class.mem]), and
- [(3.3)](#class.default.ctor-3.3)
all the direct base classes of X have trivial default constructors, and
- [(3.4)](#class.default.ctor-3.4)
either X is a union or
for all the non-variant non-static data members of X that are of class
type (or array thereof), each such class has a trivial default constructor[.](#class.default.ctor-3.sentence-1)
Otherwise, the default constructor is[*non-trivial*](#def:constructor,default,non-trivial "11.4.5.2Default constructors[class.default.ctor]")[.](#class.default.ctor-3.sentence-2)
[4](#class.default.ctor-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1425)
If a default constructor of a union-like class X is trivial,
then for each union U that is either X or an anonymous union member of X,
if the first variant member, if any, of U has implicit-lifetime type ([[basic.types.general]](basic.types.general "6.9.1General")),
the default constructor of X begins the lifetime of that member
if it is not the active member of its union[.](#class.default.ctor-4.sentence-1)
[*Note [1](#class.default.ctor-note-1)*:
It is already the active member if U was value-initialized[.](#class.default.ctor-4.sentence-2)
— *end note*]
Otherwise,
an implicitly-defined ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2Explicitly-defaulted functions")) default constructor performs the set of
initializations of the class that would be performed by a user-written default
constructor for that class with no[*ctor-initializer*](class.base.init#nt:ctor-initializer "11.9.3Initializing bases and members[class.base.init]") ([[class.base.init]](class.base.init "11.9.3Initializing bases and members")) and an empty[*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]")[.](#class.default.ctor-4.sentence-3)
If that user-written default constructor would be ill-formed,
the program is ill-formed[.](#class.default.ctor-4.sentence-4)
If that user-written default constructor would be constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6The constexpr and consteval specifiers")),
the implicitly-defined
default constructor is constexpr[.](#class.default.ctor-4.sentence-5)
Before the defaulted default constructor for a class is
implicitly defined,
all the non-user-provided default constructors for its base classes and
its non-static data members are implicitly defined[.](#class.default.ctor-4.sentence-6)
[*Note [2](#class.default.ctor-note-2)*:
An implicitly-declared default constructor has an
exception specification ([[except.spec]](except.spec "14.5Exception specifications"))[.](#class.default.ctor-4.sentence-7)
An explicitly-defaulted definition might have an
implicit exception specification, see [[dcl.fct.def]](dcl.fct.def "9.6Function definitions")[.](#class.default.ctor-4.sentence-8)
— *end note*]
[5](#class.default.ctor-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1458)
[*Note [3](#class.default.ctor-note-3)*:
A default constructor is implicitly invoked to initialize
a class object when no initializer is specified ([[dcl.init.general]](dcl.init.general "9.5.1General"))[.](#class.default.ctor-5.sentence-1)
Such a default constructor needs to be accessible ([[class.access]](class.access "11.8Member access control"))[.](#class.default.ctor-5.sentence-2)
— *end note*]
[6](#class.default.ctor-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1466)
[*Note [4](#class.default.ctor-note-4)*:
[[class.base.init]](class.base.init "11.9.3Initializing bases and members") describes the order in which constructors for base
classes and non-static data members are called and
describes how arguments can be specified for the calls to these constructors[.](#class.default.ctor-6.sentence-1)
— *end note*]
#### [11.4.5.3](#class.copy.ctor) Copy/move constructors [[class.copy.ctor]](class.copy.ctor)
[1](#class.copy.ctor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1477)
A non-template constructor for classX is
a
copy
constructor if its first parameter is of typeX&,const X&,volatile X& orconst volatile X&,
and either there are no other parameters
or else all other parameters have default arguments ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments"))[.](#class.copy.ctor-1.sentence-1)
[*Example [1](#class.copy.ctor-example-1)*:
X::X(const X&) andX::X(X&,int=1) are copy constructors[.](#class.copy.ctor-1.sentence-2)
struct X { X(int);
X(const X&, int = 1);};
X a(1); // calls X(int); X b(a, 0); // calls X(const X&, int); X c = b; // calls X(const X&, int); — *end example*]
[2](#class.copy.ctor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1512)
A non-template constructor for class X is a move constructor if its
first parameter is of type X&&, const X&&,volatile X&&, or const volatile X&&, and either there are
no other parameters or else all other parameters have default
arguments ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments"))[.](#class.copy.ctor-2.sentence-1)
[*Example [2](#class.copy.ctor-example-2)*:
Y::Y(Y&&) is a move constructor[.](#class.copy.ctor-2.sentence-2)
struct Y { Y(const Y&);
Y(Y&&);};extern Y f(int);
Y d(f(1)); // calls Y(Y&&) Y e = d; // calls Y(const Y&) — *end example*]
[3](#class.copy.ctor-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1531)
[*Note [1](#class.copy.ctor-note-1)*:
All forms of copy/move constructor can be declared for a class[.](#class.copy.ctor-3.sentence-1)
[*Example [3](#class.copy.ctor-example-3)*: struct X { X(const X&);
X(X&); // OK X(X&&);
X(const X&&); // OK, but possibly not sensible}; — *end example*]
— *end note*]
[4](#class.copy.ctor-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1546)
[*Note [2](#class.copy.ctor-note-2)*:
If a classX only has a copy constructor with a parameter of typeX&,
an initializer of typeconstX orvolatileX cannot initialize an object of typecv X[.](#class.copy.ctor-4.sentence-1)
[*Example [4](#class.copy.ctor-example-4)*: struct X { X(); // default constructor X(X&); // copy constructor with a non-const parameter};const X cx;
X x = cx; // error: X::X(X&) cannot copy cx into x — *end example*]
— *end note*]
[5](#class.copy.ctor-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1572)
A declaration of a constructor for a classX is ill-formed if its first parameter is of typecv X and either there are no other parameters or else all other parameters have
default arguments[.](#class.copy.ctor-5.sentence-1)
A member function template is never instantiated to
produce such a constructor signature[.](#class.copy.ctor-5.sentence-2)
[*Example [5](#class.copy.ctor-example-5)*: struct S {template<typename T> S(T);
S();};
S g;
void h() { S a(g); // does not instantiate the member template to produce S::S<S>(S);// uses the implicitly declared copy constructor} — *end example*]
[6](#class.copy.ctor-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1597)
If the class definition does not explicitly declare a copy constructor,
a non-explicit one is declared [*implicitly*](#def:constructor,copy,implicitly_declared "11.4.5.3Copy/move constructors[class.copy.ctor]")[.](#class.copy.ctor-6.sentence-1)
If the class definition declares a move
constructor or move assignment operator, the implicitly declared copy
constructor is defined as deleted; otherwise, it is
defaulted ([[dcl.fct.def]](dcl.fct.def "9.6Function definitions"))[.](#class.copy.ctor-6.sentence-2)
The latter case is deprecated if the class has a user-declared copy assignment
operator or a user-declared destructor ([[depr.impldec]](depr.impldec "D.6Implicit declaration of copy functions"))[.](#class.copy.ctor-6.sentence-3)
[7](#class.copy.ctor-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1607)
The implicitly-declared copy constructor for a classX will have the formX::X(const X&) if each potentially constructed subobject of a class typeM (or array thereof)
has a copy constructor whose first parameter is of typeconstM& orconstvolatileM&[.](#class.copy.ctor-7.sentence-1)[89](#footnote-89 "This implies that the reference parameter of the implicitly-declared copy constructor cannot bind to a volatile lvalue; see [diff.class].")
Otherwise, the implicitly-declared copy constructor will have the formX::X(X&)
[8](#class.copy.ctor-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1636)
If the definition of a class X does not explicitly declare
a move constructor, a non-explicit one will be
implicitly declared as defaulted if and only if
- [(8.1)](#class.copy.ctor-8.1)
X does not have a user-declared copy constructor,
- [(8.2)](#class.copy.ctor-8.2)
X does not have a user-declared copy assignment operator,
- [(8.3)](#class.copy.ctor-8.3)
X does not have a user-declared move assignment operator, and
- [(8.4)](#class.copy.ctor-8.4)
X does not have a user-declared destructor[.](#class.copy.ctor-8.sentence-1)
[*Note [3](#class.copy.ctor-note-3)*:
When the move constructor is not implicitly declared or explicitly supplied,
expressions that otherwise would have invoked the move constructor might instead invoke
a copy constructor[.](#class.copy.ctor-8.sentence-2)
— *end note*]
[9](#class.copy.ctor-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1661)
The implicitly-declared move constructor for class X will have the formX::X(X&&)
[10](#class.copy.ctor-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1667)
An implicitly-declared copy/move constructor is an
inline public member of its class[.](#class.copy.ctor-10.sentence-1)
A defaulted copy/move constructor for a class X is defined as deleted ([[dcl.fct.def.delete]](dcl.fct.def.delete "9.6.3Deleted definitions")) if X has:
- [(10.1)](#class.copy.ctor-10.1)
a potentially constructed subobject of type M (or possibly multidimensional array thereof) for which
overload resolution ([[over.match]](over.match "12.2Overload resolution")), as applied to find M's corresponding constructor,
either does not result in a usable candidate ([[over.match.general]](over.match.general "12.2.1General")) or,
in the case of a variant member, selects a non-trivial function,
- [(10.2)](#class.copy.ctor-10.2)
any potentially constructed subobject of
class type M (or possibly multidimensional array thereof)
where M has
a destructor that is deleted or inaccessible from the defaulted
constructor, or,
- [(10.3)](#class.copy.ctor-10.3)
for the copy constructor, a non-static data member of rvalue reference type[.](#class.copy.ctor-10.sentence-2)
[*Note [4](#class.copy.ctor-note-4)*:
A defaulted move constructor that is defined as deleted is ignored by overload
resolution ([[over.match]](over.match "12.2Overload resolution"), [[over.over]](over.over "12.3Address of an overload set"))[.](#class.copy.ctor-10.sentence-3)
Such a constructor would otherwise interfere with initialization from
an rvalue which can use the copy constructor instead[.](#class.copy.ctor-10.sentence-4)
— *end note*]
[11](#class.copy.ctor-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1696)
A copy/move constructor for classX is
trivial
if it is not user-provided and if
- [(11.1)](#class.copy.ctor-11.1)
classX has no virtual functions ([[class.virtual]](class.virtual "11.7.3Virtual functions"))
and no virtual base classes ([[class.mi]](class.mi "11.7.2Multiple base classes")), and
- [(11.2)](#class.copy.ctor-11.2)
the constructor selected to copy/move each direct base class subobject is trivial, and
- [(11.3)](#class.copy.ctor-11.3)
for each non-static data member ofX that is of class type (or array thereof),
the constructor selected to copy/move that member is trivial;
otherwise the copy/move constructor is[*non-trivial*](#def:constructor,copy,nontrivial "11.4.5.3Copy/move constructors[class.copy.ctor]")[.](#class.copy.ctor-11.sentence-1)
[12](#class.copy.ctor-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1724)
[*Note [5](#class.copy.ctor-note-5)*:
The copy/move constructor is implicitly defined even if the implementation elided
its odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule"), [[class.temporary]](class.temporary "6.8.7Temporary objects"))[.](#class.copy.ctor-12.sentence-1)
— *end note*]
If an implicitly-defined ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2Explicitly-defaulted functions")) constructor would be constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6The constexpr and consteval specifiers")),
the implicitly-defined
constructor is constexpr[.](#class.copy.ctor-12.sentence-2)
[13](#class.copy.ctor-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1733)
Before the defaulted copy/move constructor for a class is
implicitly defined,
all non-user-provided copy/move constructors for its
potentially constructed subobjects
are implicitly defined[.](#class.copy.ctor-13.sentence-1)
[*Note [6](#class.copy.ctor-note-6)*:
An implicitly-declared copy/move constructor has an
implied exception specification ([[except.spec]](except.spec "14.5Exception specifications"))[.](#class.copy.ctor-13.sentence-2)
— *end note*]
[14](#class.copy.ctor-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1744)
The implicitly-defined copy/move constructor for a non-union classX performs a memberwise copy/move of its bases and members[.](#class.copy.ctor-14.sentence-1)
[*Note [7](#class.copy.ctor-note-7)*:
Default member initializers of non-static data members are ignored[.](#class.copy.ctor-14.sentence-2)
— *end note*]
The order of initialization is the same as the order of initialization of bases
and members in a user-defined constructor (see [[class.base.init]](class.base.init "11.9.3Initializing bases and members"))[.](#class.copy.ctor-14.sentence-3)
Let x be either the parameter of the constructor or, for the move constructor, an
xvalue referring to the parameter[.](#class.copy.ctor-14.sentence-4)
Each base or non-static data member
is copied/moved in the manner appropriate to its type:
- [(14.1)](#class.copy.ctor-14.1)
if the member is an array, each element is
direct-initialized with the corresponding subobject of x;
- [(14.2)](#class.copy.ctor-14.2)
if a member m has rvalue reference type T&&, it is direct-initialized withstatic_cast<T&&>(x.m);
- [(14.3)](#class.copy.ctor-14.3)
otherwise, the base or member is direct-initialized with the corresponding base or member of x[.](#class.copy.ctor-14.sentence-5)
Virtual base class subobjects shall be initialized only once by
the implicitly-defined copy/move constructor (see [[class.base.init]](class.base.init "11.9.3Initializing bases and members"))[.](#class.copy.ctor-14.sentence-6)
[15](#class.copy.ctor-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1774)
The implicitly-defined copy/move constructor for a unionX copies the object representation ([[basic.types.general]](basic.types.general#term.object.representation "6.9.1General")) of X[.](#class.copy.ctor-15.sentence-1)
For each object nested within ([[intro.object]](intro.object "6.8.2Object model"))
the object that is the source of the copy,
a corresponding object o nested within the destination
is identified (if the object is a subobject) or created (otherwise),
and the lifetime of o begins before the copy is performed[.](#class.copy.ctor-15.sentence-2)
[89)](#footnote-89)[89)](#footnoteref-89)
This implies that the reference parameter of the
implicitly-declared copy constructor
cannot bind to avolatile lvalue; see [[diff.class]](diff.class "C.7.7[class]: classes")[.](#footnote-89.sentence-1)
### [11.4.6](#class.copy.assign) Copy/move assignment operator [[class.copy.assign]](class.copy.assign)
[1](#class.copy.assign-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1787)
A user-declared [*copy*](#def:copy) assignment operator X::operator= is a
non-static non-template member function of class X with exactly one
non-object parameter of type X, X&, const X&,volatile X&, or const volatile X&[.](#class.copy.assign-1.sentence-1)[90](#footnote-90 "Because a template assignment operator or an assignment operator taking an rvalue reference parameter is never a copy assignment operator, the presence of such an assignment operator does not suppress the implicit declaration of a copy assignment operator. Such assignment operators participate in overload resolution with other assignment operators, including copy assignment operators, and, if selected, will be used to assign an object.")
[*Note [1](#class.copy.assign-note-1)*:
More than one form of copy assignment operator can be declared for a class[.](#class.copy.assign-1.sentence-2)
— *end note*]
[*Note [2](#class.copy.assign-note-2)*:
If a classX only has a copy assignment operator with a non-object parameter of typeX&,
an expression of type constX cannot be assigned to an object of typeX[.](#class.copy.assign-1.sentence-3)
[*Example [1](#class.copy.assign-example-1)*: struct X { X();
X& operator=(X&);};const X cx;
X x;void f() { x = cx; // error: X::operator=(X&) cannot assign cx into x} — *end example*]
— *end note*]
[2](#class.copy.assign-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1835)
If the class definition does not explicitly declare a copy assignment operator,
one is declared [*implicitly*](#def:assignment_operator,copy,implicitly_declared "11.4.6Copy/move assignment operator[class.copy.assign]")[.](#class.copy.assign-2.sentence-1)
If the class definition declares a move
constructor or move assignment operator, the implicitly declared copy
assignment operator is defined as deleted; otherwise, it is
defaulted ([[dcl.fct.def]](dcl.fct.def "9.6Function definitions"))[.](#class.copy.assign-2.sentence-2)
The latter case is deprecated if the class has a user-declared copy constructor
or a user-declared destructor ([[depr.impldec]](depr.impldec "D.6Implicit declaration of copy functions"))[.](#class.copy.assign-2.sentence-3)
The implicitly-declared copy assignment operator for a classX will have the formX& X::operator=(const X&) if
- [(2.1)](#class.copy.assign-2.1)
each direct base class B of X has a copy assignment operator whose non-object parameter is of typeconst B&, const volatile B&, or B, and
- [(2.2)](#class.copy.assign-2.2)
for all the non-static data members of X that are of a class type M (or array thereof),
each such class type has a copy assignment operator whose non-object parameter is of typeconst M&, const volatile M&,
or M[.](#class.copy.assign-2.sentence-4)[91](#footnote-91 "This implies that the reference parameter of the implicitly-declared copy assignment operator cannot bind to a volatile lvalue; see [diff.class].")
Otherwise, the implicitly-declared copy assignment operator
will have the formX& X::operator=(X&)
[3](#class.copy.assign-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1875)
A user-declared move assignment operator X::operator= is
a non-static non-template member function of class X with exactly
one non-object parameter of type X&&, const X&&, volatile X&&, orconst volatile X&&[.](#class.copy.assign-3.sentence-1)
[*Note [3](#class.copy.assign-note-3)*:
More than one form of move assignment operator can be declared for a class[.](#class.copy.assign-3.sentence-2)
— *end note*]
[4](#class.copy.assign-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1884)
If the definition of a class X does not explicitly declare a
move assignment operator, one
will be implicitly declared as defaulted if and only if
- [(4.1)](#class.copy.assign-4.1)
X does not have a user-declared copy constructor,
- [(4.2)](#class.copy.assign-4.2)
X does not have a user-declared move constructor,
- [(4.3)](#class.copy.assign-4.3)
X does not have a user-declared copy assignment operator, and
- [(4.4)](#class.copy.assign-4.4)
X does not have a user-declared destructor[.](#class.copy.assign-4.sentence-1)
[*Example [2](#class.copy.assign-example-2)*:
The class definitionstruct S {int a;
S& operator=(const S&) = default;}; will not have a default move assignment operator implicitly declared because the
copy assignment operator has been user-declared[.](#class.copy.assign-4.sentence-2)
The move assignment operator may
be explicitly defaulted[.](#class.copy.assign-4.sentence-3)
struct S {int a;
S& operator=(const S&) = default;
S& operator=(S&&) = default;}; — *end example*]
[5](#class.copy.assign-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1924)
The implicitly-declared move assignment operator for a class X will have the formX& X::operator=(X&&)
[6](#class.copy.assign-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1930)
The implicitly-declared copy/move assignment operator for classX has the return typeX&[.](#class.copy.assign-6.sentence-1)
An implicitly-declared copy/move assignment operator is an
inline public member of its class[.](#class.copy.assign-6.sentence-2)
[7](#class.copy.assign-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1938)
A defaulted copy/move assignment operator for
class X is defined as deleted if X has:
- [(7.1)](#class.copy.assign-7.1)
a non-static data member of const non-class
type (or possibly multidimensional array thereof), or
- [(7.2)](#class.copy.assign-7.2)
a non-static data member of reference type, or
- [(7.3)](#class.copy.assign-7.3)
a direct non-static data member of class type M (or possibly multidimensional array thereof) or
a direct base class M that cannot be copied/moved because overload resolution ([[over.match]](over.match "12.2Overload resolution")),
as applied to find M's corresponding assignment operator,
either does not result in a usable candidate ([[over.match.general]](over.match.general "12.2.1General")) or,
in the case of a variant member, selects a non-trivial function[.](#class.copy.assign-7.sentence-1)
[*Note [4](#class.copy.assign-note-4)*:
A defaulted move assignment operator that is defined as deleted is ignored by
overload resolution ([[over.match]](over.match "12.2Overload resolution"), [[over.over]](over.over "12.3Address of an overload set"))[.](#class.copy.assign-7.sentence-2)
— *end note*]
[8](#class.copy.assign-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1961)
Because a copy/move assignment operator is implicitly declared for a class
if not declared by the user,
a base class copy/move assignment operator is always hidden
by the corresponding assignment operator of a derived class ([[over.assign]](over.assign "12.4.3.2Simple assignment"))[.](#class.copy.assign-8.sentence-1)
[*Note [5](#class.copy.assign-note-5)*:
A [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]") in a derived class C that names an assignment operator from a base class
never suppresses the implicit declaration of
an assignment operator of C,
even if the base class assignment operator would be
a copy or move assignment operator
if declared as a member of C[.](#class.copy.assign-8.sentence-2)
— *end note*]
[9](#class.copy.assign-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1978)
A copy/move assignment operator for classX is
trivial
if it is not user-provided and if
- [(9.1)](#class.copy.assign-9.1)
classX has no virtual functions ([[class.virtual]](class.virtual "11.7.3Virtual functions"))
and no virtual base classes ([[class.mi]](class.mi "11.7.2Multiple base classes")), and
- [(9.2)](#class.copy.assign-9.2)
the assignment operator selected to copy/move each direct
base class subobject is trivial, and
- [(9.3)](#class.copy.assign-9.3)
for each non-static data member ofX that is of class type (or array thereof),
the assignment operator selected to copy/move that member is trivial;
otherwise the copy/move assignment operator is[*non-trivial*](#def:assignment_operator,copy,non-trivial "11.4.6Copy/move assignment operator[class.copy.assign]")[.](#class.copy.assign-9.sentence-1)
[10](#class.copy.assign-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2006)
An implicitly-defined ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2Explicitly-defaulted functions")) copy/move assignment operator is constexpr[.](#class.copy.assign-10.sentence-1)
[11](#class.copy.assign-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2009)
Before the defaulted copy/move assignment operator for a class is
implicitly defined,
all non-user-provided copy/move assignment operators for
its direct base classes and
its non-static data members are implicitly defined[.](#class.copy.assign-11.sentence-1)
[*Note [6](#class.copy.assign-note-6)*:
An implicitly-declared copy/move assignment operator has an
implied exception specification ([[except.spec]](except.spec "14.5Exception specifications"))[.](#class.copy.assign-11.sentence-2)
— *end note*]
[12](#class.copy.assign-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2020)
The implicitly-defined copy/move assignment operator for a
non-union class X performs memberwise copy/move assignment of its subobjects[.](#class.copy.assign-12.sentence-1)
The direct
base classes of X are assigned first, in the order of their declaration in the[*base-specifier-list*](class.derived.general#nt:base-specifier-list "11.7.1General[class.derived.general]"), and then the immediate non-static data members ofX are assigned, in the order in which they were declared in the class
definition[.](#class.copy.assign-12.sentence-2)
Let x be either the parameter of the function or, for the move operator, an
xvalue referring to the parameter[.](#class.copy.assign-12.sentence-3)
Each subobject is assigned in the manner appropriate to its type:
- [(12.1)](#class.copy.assign-12.1)
if the subobject is of class type,
as if by a call to operator= with the subobject as the object expression
and the corresponding subobject of x as a single function argument
(as if by explicit qualification; that is,
ignoring any possible virtual overriding functions in more derived classes);
- [(12.2)](#class.copy.assign-12.2)
if the subobject is an array, each element is assigned,
in the manner appropriate to the element type;
- [(12.3)](#class.copy.assign-12.3)
if the subobject is of scalar type,
the built-in assignment operator is used[.](#class.copy.assign-12.sentence-4)
It is unspecified whether subobjects representing virtual base classes
are assigned more than once by the implicitly-defined copy/move assignment
operator[.](#class.copy.assign-12.sentence-5)
[*Example [3](#class.copy.assign-example-3)*: struct V { };struct A : virtual V { };struct B : virtual V { };struct C : B, A { };
It is unspecified whether the virtual base class subobjectV is assigned twice by the implicitly-defined copy/move assignment operator forC[.](#class.copy.assign-12.sentence-6)
— *end example*]
[13](#class.copy.assign-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2063)
The implicitly-defined copy/move assignment operator for a
union X copies the object representation ([[basic.types.general]](basic.types.general#term.object.representation "6.9.1General")) of X[.](#class.copy.assign-13.sentence-1)
If the source and destination of the assignment are not the same object, then
for each object nested within ([[intro.object]](intro.object "6.8.2Object model"))
the object that is the source of the copy,
a corresponding object o nested within the destination is created,
and the lifetime of o begins before the copy is performed[.](#class.copy.assign-13.sentence-2)
[14](#class.copy.assign-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2072)
The implicitly-defined copy/move assignment operator for a class
returns the object for which the assignment operator is invoked,
that is, the object assigned to[.](#class.copy.assign-14.sentence-1)
[90)](#footnote-90)[90)](#footnoteref-90)
Because
a template assignment operator or an assignment operator
taking an rvalue reference parameter is never a copy assignment operator,
the presence of such an assignment operator does not suppress the
implicit declaration of a copy assignment operator[.](#footnote-90.sentence-1)
Such assignment operators
participate in overload resolution with other assignment operators, including
copy assignment operators, and, if selected, will be used to assign an object[.](#footnote-90.sentence-2)
[91)](#footnote-91)[91)](#footnoteref-91)
This implies that the reference parameter of the
implicitly-declared copy assignment operator cannot bind to avolatile lvalue; see [[diff.class]](diff.class "C.7.7[class]: classes")[.](#footnote-91.sentence-1)
### [11.4.7](#class.dtor) Destructors [[class.dtor]](class.dtor)
[1](#class.dtor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2082)
A declaration whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") has an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") that begins with a ~ declares a [*prospective destructor*](#def:destructor,prospective "11.4.7Destructors[class.dtor]");
its [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") shall be a function declarator ([[dcl.fct]](dcl.fct "9.3.4.6Functions")) of the form
[*ptr-declarator*](dcl.decl.general#nt:ptr-declarator "9.3.1General[dcl.decl.general]") ( [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6Functions[dcl.fct]") ) [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5Exception specifications[except.spec]")opt [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
where the [*ptr-declarator*](dcl.decl.general#nt:ptr-declarator "9.3.1General[dcl.decl.general]") consists solely of an[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]"), an optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]"),
and optional surrounding parentheses, and the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") has
one of the following forms:
- [(1.1)](#class.dtor-1.1)
in a [*member-declaration*](#nt:member-declaration "11.4.1General[class.mem.general]") that belongs to the[*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]") of a class or class template
but is not a friend
declaration ([[class.friend]](class.friend "11.8.4Friends")), the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") is~[*class-name*](class.pre#nt:class-name "11.1Preamble[class.pre]") and the [*class-name*](class.pre#nt:class-name "11.1Preamble[class.pre]") is the
injected-class-name ([[class.pre]](class.pre "11.1Preamble")) of the immediately-enclosing entity or
- [(1.2)](#class.dtor-1.2)
otherwise, the[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") is [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")~[*class-name*](class.pre#nt:class-name "11.1Preamble[class.pre]") and the [*class-name*](class.pre#nt:class-name "11.1Preamble[class.pre]") is the injected-class-name of the
class nominated by the [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")[.](#class.dtor-1.sentence-1)
A prospective destructor shall take no arguments ([[dcl.fct]](dcl.fct "9.3.4.6Functions"))[.](#class.dtor-1.sentence-2)
Each [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1General[dcl.spec.general]") of the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") of a prospective destructor declaration (if any)
shall befriend,inline,virtual, orconstexpr[.](#class.dtor-1.sentence-3)
[2](#class.dtor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2120)
If a class has no user-declared
prospective destructor,
a prospective destructor is implicitly
declared as defaulted ([[dcl.fct.def]](dcl.fct.def "9.6Function definitions"))[.](#class.dtor-2.sentence-1)
An implicitly-declared prospective destructor is an
inline public member of its class[.](#class.dtor-2.sentence-2)
[3](#class.dtor-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2130)
An implicitly-declared prospective destructor for a class X will have the form~X()
[4](#class.dtor-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2136)
At the end of the definition of a class,
overload resolution is performed
among the prospective destructors declared in that class
with an empty argument list
to select the [*destructor*](#def:destructor "11.4.7Destructors[class.dtor]") for the class,
also known as the [*selected destructor*](#def:destructor,selected "11.4.7Destructors[class.dtor]")[.](#class.dtor-4.sentence-1)
The program is ill-formed if overload resolution fails[.](#class.dtor-4.sentence-2)
Destructor selection does not constitute
a reference to,
or odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule")) of,
the selected destructor,
and in particular,
the selected destructor may be deleted ([[dcl.fct.def.delete]](dcl.fct.def.delete "9.6.3Deleted definitions"))[.](#class.dtor-4.sentence-3)
[5](#class.dtor-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2151)
The address of a destructor shall not be taken[.](#class.dtor-5.sentence-1)
[*Note [1](#class.dtor-note-1)*:
A return statement in the body of a destructor
cannot specify a return value ([[stmt.return]](stmt.return "8.8.4The return statement"))[.](#class.dtor-5.sentence-2)
— *end note*]
A destructor can be invoked for aconst,volatile orconstvolatile object[.](#class.dtor-5.sentence-3)
const andvolatile semantics ([[dcl.type.cv]](dcl.type.cv "9.2.9.2The cv-qualifiers")) are not applied on an object under destruction[.](#class.dtor-5.sentence-4)
They stop being in effect when the destructor for the
most derived object ([[intro.object]](intro.object "6.8.2Object model")) starts[.](#class.dtor-5.sentence-5)
[6](#class.dtor-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2175)
[*Note [2](#class.dtor-note-2)*:
A declaration of a destructor that does not have a [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5Exception specifications[except.spec]") has the same exception specification as if it had been implicitly declared ([[except.spec]](except.spec "14.5Exception specifications"))[.](#class.dtor-6.sentence-1)
— *end note*]
[7](#class.dtor-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2181)
A defaulted destructor for a class X is defined as deleted if
- [(7.1)](#class.dtor-7.1)
X is a non-union class and
any non-variant potentially constructed subobject has class type M (or possibly multidimensional array thereof) where M has a destructor that is deleted or
is inaccessible from the defaulted destructor,
- [(7.2)](#class.dtor-7.2)
X is a union and
* [(7.2.1)](#class.dtor-7.2.1)
overload resolution to select a constructor to
default-initialize an object of type X either fails or
selects a constructor that is either deleted or not trivial, or
* [(7.2.2)](#class.dtor-7.2.2)
X has a variant member V of
class type M (or possibly multi-dimensional array thereof)
where V has a default member initializer and M has a destructor that is non-trivial, or,
- [(7.3)](#class.dtor-7.3)
for a virtual destructor, lookup of the non-array deallocation
function results in an ambiguity or in a function that is deleted or
inaccessible from the defaulted destructor[.](#class.dtor-7.sentence-1)
[8](#class.dtor-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2210)
A destructor for a class X is trivial if it is not user-provided and if
- [(8.1)](#class.dtor-8.1)
the destructor is not virtual,
- [(8.2)](#class.dtor-8.2)
all of the direct base classes of X have trivial destructors, and
- [(8.3)](#class.dtor-8.3)
either X is a union or
for all of the non-variant non-static data members of X that are of class
type (or array thereof), each such class has a trivial destructor[.](#class.dtor-8.sentence-1)
Otherwise, the destructor is[*non-trivial*](#def:destructor,non-trivial "11.4.7Destructors[class.dtor]")[.](#class.dtor-8.sentence-2)
[9](#class.dtor-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2225)
A defaulted destructor is a constexpr destructor
if it is constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6The constexpr and consteval specifiers"))[.](#class.dtor-9.sentence-1)
[10](#class.dtor-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2229)
Before a
defaulted destructor for a class is implicitly defined, all the non-user-provided
destructors for its base classes and its non-static data members are
implicitly defined[.](#class.dtor-10.sentence-1)
[11](#class.dtor-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2235)
A prospective destructor can be
declared virtual ([[class.virtual]](class.virtual "11.7.3Virtual functions"))
and with a [*pure-specifier*](#nt:pure-specifier "11.4.1General[class.mem.general]") ([[class.abstract]](class.abstract "11.7.4Abstract classes"))[.](#class.dtor-11.sentence-1)
If the destructor of a class is virtual and
any objects of that class or any derived class are created in the program,
the destructor shall be defined[.](#class.dtor-11.sentence-2)
[12](#class.dtor-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2245)
[*Note [3](#class.dtor-note-3)*:
Some language constructs have special semantics when used during destruction;
see [[class.cdtor]](class.cdtor "11.9.5Construction and destruction")[.](#class.dtor-12.sentence-1)
— *end note*]
[13](#class.dtor-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2252)
After executing the body of the destructor and destroying
any objects with automatic storage duration allocated within the body, a
destructor for classX calls the destructors forX's
direct non-variant non-static data members other than anonymous unions,
the destructors forX's
non-virtual direct base classes and, ifX is the most derived class ([[class.base.init]](class.base.init "11.9.3Initializing bases and members")),
its destructor calls the destructors forX's
virtual base classes[.](#class.dtor-13.sentence-1)
All destructors are called as if they were referenced with a qualified name,
that is, ignoring any possible virtual overriding destructors in more
derived classes[.](#class.dtor-13.sentence-2)
Bases and members are destroyed in the reverse order of the completion of
their constructor (see [[class.base.init]](class.base.init "11.9.3Initializing bases and members"))[.](#class.dtor-13.sentence-3)
[*Note [4](#class.dtor-note-4)*:
Areturn statement ([[stmt.return]](stmt.return "8.8.4The return statement")) in a destructor might not directly return to the
caller; before transferring control to the caller, the destructors for the
members and bases are called[.](#class.dtor-13.sentence-4)
— *end note*]
Destructors for elements of an array are called in reverse order of their
construction (see [[class.init]](class.init "11.9Initialization"))[.](#class.dtor-13.sentence-5)
[14](#class.dtor-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2287)
A destructor is invoked implicitly
- [(14.1)](#class.dtor-14.1)
for a constructed object with static storage duration ([[basic.stc.static]](basic.stc.static "6.8.6.2Static storage duration")) at program termination ([[basic.start.term]](basic.start.term "6.10.3.4Termination")),
- [(14.2)](#class.dtor-14.2)
for a constructed object with thread storage duration ([[basic.stc.thread]](basic.stc.thread "6.8.6.3Thread storage duration")) at thread exit,
- [(14.3)](#class.dtor-14.3)
for a constructed object with automatic storage duration ([[basic.stc.auto]](basic.stc.auto "6.8.6.4Automatic storage duration")) when the block in which an object is created exits ([[stmt.dcl]](stmt.dcl "8.10Declaration statement")),
- [(14.4)](#class.dtor-14.4)
for a constructed temporary object when its lifetime ends ([[conv.rval]](conv.rval "7.3.5Temporary materialization conversion"), [[class.temporary]](class.temporary "6.8.7Temporary objects"))[.](#class.dtor-14.sentence-1)
In each case, the context of the invocation is the context of the construction of
the object[.](#class.dtor-14.sentence-2)
A destructor may also be invoked implicitly through use of a[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]") ([[expr.delete]](expr.delete "7.6.2.9Delete")) for a constructed object allocated
by a [*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]") ([[expr.new]](expr.new "7.6.2.8New")); the context of the invocation is the[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]")[.](#class.dtor-14.sentence-3)
[*Note [5](#class.dtor-note-5)*:
An array of class type contains several subobjects for each of which
the destructor is invoked[.](#class.dtor-14.sentence-4)
— *end note*]
A destructor can also be invoked explicitly[.](#class.dtor-14.sentence-5)
A destructor is [*potentially invoked*](#def:potentially_invoked "11.4.7Destructors[class.dtor]") if it is invoked or as specified in [[expr.new]](expr.new "7.6.2.8New"),[[stmt.return]](stmt.return "8.8.4The return statement"), [[dcl.init.aggr]](dcl.init.aggr "9.5.2Aggregates"),[[class.base.init]](class.base.init "11.9.3Initializing bases and members"), and [[except.throw]](except.throw "14.2Throwing an exception")[.](#class.dtor-14.sentence-6)
A program is ill-formed if a destructor that is potentially invoked is deleted
or not accessible from the context of the invocation[.](#class.dtor-14.sentence-7)
[15](#class.dtor-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2319)
At the point of definition of a virtual destructor (including an implicit
definition), the non-array deallocation function is
determined as if for the expression delete this appearing in a
non-virtual destructor of the destructor's class (see [[expr.delete]](expr.delete "7.6.2.9Delete"))[.](#class.dtor-15.sentence-1)
If the lookup fails or if the deallocation function has
a deleted definition ([[dcl.fct.def]](dcl.fct.def "9.6Function definitions")), the program is ill-formed[.](#class.dtor-15.sentence-2)
[*Note [6](#class.dtor-note-6)*:
This assures that a deallocation function corresponding to the dynamic type of an
object is available for the[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]") ([[class.free]](#class.free "11.4.11Allocation and deallocation functions"))[.](#class.dtor-15.sentence-3)
— *end note*]
[16](#class.dtor-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2332)
In an explicit destructor call, the destructor is specified by a~ followed by a[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]") or [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]") that denotes the destructor's class type[.](#class.dtor-16.sentence-1)
The invocation of a destructor is subject to the usual rules for member
functions ([[class.mfct]](#class.mfct "11.4.2Member functions"));
that is, if the object is not of the destructor's class type and
not of a class derived from the destructor's class type (including when
the destructor is invoked via a null pointer value), the program has
undefined behavior[.](#class.dtor-16.sentence-2)
[*Note [7](#class.dtor-note-7)*:
Invoking delete on a null pointer does not call the
destructor; see [[expr.delete]](expr.delete "7.6.2.9Delete")[.](#class.dtor-16.sentence-3)
— *end note*]
[*Example [1](#class.dtor-example-1)*: struct B {virtual ~B() { }};struct D : B {~D() { }};
D D_object;typedef B B_alias;
B* B_ptr = &D_object;
void f() { D_object.B::~B(); // calls B's destructor B_ptr->~B(); // calls D's destructor B_ptr->~B_alias(); // calls D's destructor B_ptr->B_alias::~B(); // calls B's destructor B_ptr->B_alias::~B_alias(); // calls B's destructor} — *end example*]
[*Note [8](#class.dtor-note-8)*:
An explicit destructor call must always be written using
a member access operator ([[expr.ref]](expr.ref "7.6.1.5Class member access")) or a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3Qualified names"));
in particular, the[*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1General[expr.unary.general]")~X() in a member function is not an explicit destructor call ([[expr.unary.op]](expr.unary.op "7.6.2.2Unary operators"))[.](#class.dtor-16.sentence-4)
— *end note*]
[17](#class.dtor-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2380)
[*Note [9](#class.dtor-note-9)*:
Explicit calls of destructors are rarely needed[.](#class.dtor-17.sentence-1)
One use of such calls is for objects placed at specific
addresses using a placement[*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]")[.](#class.dtor-17.sentence-2)
Such use of explicit placement and destruction of objects can be necessary
to cope with dedicated hardware resources and for writing memory management
facilities[.](#class.dtor-17.sentence-3)
[*Example [2](#class.dtor-example-2)*: void* operator new(std::size_t, void* p) { return p; }struct X { X(int); ~X();};void f(X* p);
void g() { // rare, specialized use:char* buf = new char[sizeof(X)];
X* p = new(buf) X(222); // use buf[] and initialize f(p);
p->X::~X(); // cleanup} — *end example*]
— *end note*]
[18](#class.dtor-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2409)
Once a destructor is invoked for an object, the object's lifetime ends;
the behavior is undefined if the destructor is invoked
for an object whose lifetime has ended ([[basic.life]](basic.life "6.8.4Lifetime"))[.](#class.dtor-18.sentence-1)
[*Example [3](#class.dtor-example-3)*:
If the destructor for an object with automatic storage duration is explicitly invoked,
and the block is subsequently left in a manner that would ordinarily
invoke implicit destruction of the object, the behavior is undefined[.](#class.dtor-18.sentence-2)
— *end example*]
[19](#class.dtor-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2419)
[*Note [10](#class.dtor-note-10)*:
The notation for explicit call of a destructor can be used for any scalar type
name ([[expr.prim.id.dtor]](expr.prim.id.dtor "7.5.5.5Destruction"))[.](#class.dtor-19.sentence-1)
Allowing this makes it possible to write code without having to know if a
destructor exists for a given type[.](#class.dtor-19.sentence-2)
For example:typedef int I;
I* p;
p->I::~I();
— *end note*]
[20](#class.dtor-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2434)
A destructor shall not be a coroutine[.](#class.dtor-20.sentence-1)
### [11.4.8](#class.conv) Conversions [[class.conv]](class.conv)
#### [11.4.8.1](#class.conv.general) General [[class.conv.general]](class.conv.general)
[1](#class.conv.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2441)
Type conversions of class objects can be specified by constructors and
by conversion functions[.](#class.conv.general-1.sentence-1)
These conversions are called[*user-defined conversions*](#def:conversion,user-defined "11.4.8.1General[class.conv.general]") and are used for implicit type conversions ([[conv]](conv "7.3Standard conversions")),
for initialization ([[dcl.init]](dcl.init "9.5Initializers")),
and for explicit type conversions ([[expr.type.conv]](expr.type.conv "7.6.1.4Explicit type conversion (functional notation)"), [[expr.cast]](expr.cast "7.6.3Explicit type conversion (cast notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9Static cast"))[.](#class.conv.general-1.sentence-2)
[2](#class.conv.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2455)
User-defined conversions are applied only where they are unambiguous ([[class.member.lookup]](class.member.lookup "6.5.2Member name lookup"), [[class.conv.fct]](#class.conv.fct "11.4.8.3Conversion functions"))[.](#class.conv.general-2.sentence-1)
Conversions obey the access control rules ([[class.access]](class.access "11.8Member access control"))[.](#class.conv.general-2.sentence-2)
Access control is applied after ambiguity resolution ([[basic.lookup]](basic.lookup "6.5Name lookup"))[.](#class.conv.general-2.sentence-3)
[3](#class.conv.general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2460)
[*Note [1](#class.conv.general-note-1)*:
See [[over.match]](over.match "12.2Overload resolution") for a discussion of the use of conversions in function calls[.](#class.conv.general-3.sentence-1)
— *end note*]
[4](#class.conv.general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2465)
At most one user-defined conversion (constructor or conversion function)
is implicitly applied to a single value[.](#class.conv.general-4.sentence-1)
[*Example [1](#class.conv.general-example-1)*: struct X {operator int();};
struct Y {operator X();};
Y a;int b = a; // error: no viable conversion (a.operator X().operator int() not considered)int c = X(a); // OK, a.operator X().operator int() — *end example*]
#### [11.4.8.2](#class.conv.ctor) Conversion by constructor [[class.conv.ctor]](class.conv.ctor)
[1](#class.conv.ctor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2488)
A constructor that is not explicit ([[dcl.fct.spec]](dcl.fct.spec "9.2.3Function specifiers"))
specifies a conversion from
the types of its parameters (if any)
to the type of its class[.](#class.conv.ctor-1.sentence-1)
[*Example [1](#class.conv.ctor-example-1)*:
[🔗](#:Jessie)
struct X { X(int);
X(const char*, int = 0);
X(int, int);};
void f(X arg) { X a = 1; // a = X(1) X b = "Jessie"; // b = X("Jessie",0) a = 2; // a = X(2) f(3); // f(X(3)) f({1, 2}); // f(X(1,2))} — *end example*]
[2](#class.conv.ctor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2512)
[*Note [1](#class.conv.ctor-note-1)*:
An explicit constructor constructs objects just like non-explicit
constructors, but does so only where the direct-initialization syntax ([[dcl.init]](dcl.init "9.5Initializers"))
or where casts ([[expr.static.cast]](expr.static.cast "7.6.1.9Static cast"), [[expr.cast]](expr.cast "7.6.3Explicit type conversion (cast notation)")) are explicitly
used; see also [[over.match.copy]](over.match.copy "12.2.2.5Copy-initialization of class by user-defined conversion")[.](#class.conv.ctor-2.sentence-1)
A default constructor can be an explicit constructor; such a constructor
will be used to perform default-initialization
or value-initialization ([[dcl.init]](dcl.init "9.5Initializers"))[.](#class.conv.ctor-2.sentence-2)
[*Example [2](#class.conv.ctor-example-2)*: struct Z {explicit Z(); explicit Z(int); explicit Z(int, int);};
Z a; // OK, default-initialization performed Z b{}; // OK, direct initialization syntax used Z c = {}; // error: copy-list-initialization Z a1 = 1; // error: no implicit conversion Z a3 = Z(1); // OK, direct initialization syntax used Z a2(1); // OK, direct initialization syntax used Z* p = new Z(1); // OK, direct initialization syntax used Z a4 = (Z)1; // OK, explicit cast used Z a5 = static_cast<Z>(1); // OK, explicit cast used Z a6 = { 3, 4 }; // error: no implicit conversion — *end example*]
— *end note*]
#### [11.4.8.3](#class.conv.fct) Conversion functions [[class.conv.fct]](class.conv.fct)
[conversion-function-id:](#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]")
operator [*conversion-type-id*](#nt:conversion-type-id "11.4.8.3Conversion functions[class.conv.fct]")
[conversion-type-id:](#nt:conversion-type-id "11.4.8.3Conversion functions[class.conv.fct]")
[*type-specifier-seq*](dcl.type.general#nt:type-specifier-seq "9.2.9.1General[dcl.type.general]") [*conversion-declarator*](#nt:conversion-declarator "11.4.8.3Conversion functions[class.conv.fct]")opt
[conversion-declarator:](#nt:conversion-declarator "11.4.8.3Conversion functions[class.conv.fct]")
[*ptr-operator*](dcl.decl.general#nt:ptr-operator "9.3.1General[dcl.decl.general]") [*conversion-declarator*](#nt:conversion-declarator "11.4.8.3Conversion functions[class.conv.fct]")opt
[1](#class.conv.fct-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2563)
A declaration
whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") has
an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") that is a [*conversion-function-id*](#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]") declares a [*conversion function*](#def:function,conversion "11.4.8.3Conversion functions[class.conv.fct]");
its [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") shall be
a function declarator ([[dcl.fct]](dcl.fct "9.3.4.6Functions")) of the form
[*noptr-declarator*](dcl.decl.general#nt:noptr-declarator "9.3.1General[dcl.decl.general]") [*parameters-and-qualifiers*](dcl.decl.general#nt:parameters-and-qualifiers "9.3.1General[dcl.decl.general]")
where the [*noptr-declarator*](dcl.decl.general#nt:noptr-declarator "9.3.1General[dcl.decl.general]") consists solely of
an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]"),
an optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]"), and
optional surrounding parentheses, and
the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") has one of the following forms:
- [(1.1)](#class.conv.fct-1.1)
in a [*member-declaration*](#nt:member-declaration "11.4.1General[class.mem.general]") that belongs to
the [*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]") of a class or class template
but is not a friend declaration ([[class.friend]](class.friend "11.8.4Friends")),
the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") is a [*conversion-function-id*](#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]");
- [(1.2)](#class.conv.fct-1.2)
otherwise, the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") whose [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") is a [*conversion-function-id*](#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]")[.](#class.conv.fct-1.sentence-1)
[2](#class.conv.fct-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2589)
A conversion function shall have no non-object parameters and
shall be a non-static member function of a class or class template X;
its declared return type is the [*conversion-type-id*](#nt:conversion-type-id "11.4.8.3Conversion functions[class.conv.fct]") and
it specifies a conversion from X to
the type specified by the [*conversion-type-id*](#nt:conversion-type-id "11.4.8.3Conversion functions[class.conv.fct]"),
interpreted as a [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") ([[dcl.name]](dcl.name "9.3.2Type names"))[.](#class.conv.fct-2.sentence-1)
A [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1General[dcl.spec.general]") in the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") of a conversion function (if any) shall not be
a [*defining-type-specifier*](dcl.type.general#nt:defining-type-specifier "9.2.9.1General[dcl.type.general]")[.](#class.conv.fct-2.sentence-2)
[3](#class.conv.fct-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2600)
[*Note [1](#class.conv.fct-note-1)*:
A conversion function is never invoked for
implicit or explicit conversions of an object
to the same object type (or a reference to it),
to a base class of that type (or a reference to it),
or to cv void[.](#class.conv.fct-3.sentence-1)
Even though never directly called to perform a conversion,
such conversion functions can be declared and can potentially
be reached through a call to a virtual conversion function in a base class[.](#class.conv.fct-3.sentence-2)
— *end note*]
[*Example [1](#class.conv.fct-example-1)*: struct X {operator int(); operator auto() -> short; // error: trailing return type};
void f(X a) {int i = int(a);
i = (int)a;
i = a;}
In all three cases the value assigned will be converted byX::operator int()[.](#class.conv.fct-3.sentence-3)
— *end example*]
[4](#class.conv.fct-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2628)
A conversion function may be explicit ([[dcl.fct.spec]](dcl.fct.spec "9.2.3Function specifiers")), in which case it is only considered as a user-defined conversion for direct-initialization ([[dcl.init]](dcl.init "9.5Initializers"))[.](#class.conv.fct-4.sentence-1)
Otherwise, user-defined conversions are not restricted to use in assignments and initializations[.](#class.conv.fct-4.sentence-2)
[*Example [2](#class.conv.fct-example-2)*: class Y { };struct Z {explicit operator Y() const;};
void h(Z z) { Y y1(z); // OK, direct-initialization Y y2 = z; // error: no conversion function candidate for copy-initialization Y y3 = (Y)z; // OK, cast notation}void g(X a, X b) {int i = (a) ? 1+a : 0; int j = (a&&b) ? a+b : i; if (a) {}} — *end example*]
[5](#class.conv.fct-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2652)
The[*conversion-type-id*](#nt:conversion-type-id "11.4.8.3Conversion functions[class.conv.fct]") shall not represent a function type nor an array type[.](#class.conv.fct-5.sentence-1)
The[*conversion-type-id*](#nt:conversion-type-id "11.4.8.3Conversion functions[class.conv.fct]") in a[*conversion-function-id*](#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]") is the longest sequence of
tokens that could possibly form a [*conversion-type-id*](#nt:conversion-type-id "11.4.8.3Conversion functions[class.conv.fct]")[.](#class.conv.fct-5.sentence-2)
[*Note [2](#class.conv.fct-note-2)*:
This prevents ambiguities between the declarator operator * and its expression
counterparts[.](#class.conv.fct-5.sentence-3)
[*Example [3](#class.conv.fct-example-3)*: &ac.operator int*i; // syntax error:// parsed as: &(ac.operator int *)i// not as: &(ac.operator int)*i
The * is the pointer declarator and not the multiplication operator[.](#class.conv.fct-5.sentence-4)
— *end example*]
This rule also prevents ambiguities for attributes[.](#class.conv.fct-5.sentence-5)
[*Example [4](#class.conv.fct-example-4)*: operator int [[noreturn]] (); // error: noreturn attribute applied to a type — *end example*]
— *end note*]
[6](#class.conv.fct-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2681)
[*Note [3](#class.conv.fct-note-3)*:
A conversion function in a derived class hides only
conversion functions in base classes that convert to the same type[.](#class.conv.fct-6.sentence-1)
A conversion function template with a dependent return type hides only
templates in base classes that correspond to it ([[class.member.lookup]](class.member.lookup "6.5.2Member name lookup"));
otherwise, it hides and is hidden as a non-template function[.](#class.conv.fct-6.sentence-2)
Function overload resolution ([[over.match.best]](over.match.best "12.2.4Best viable function")) selects
the best conversion function to perform the conversion[.](#class.conv.fct-6.sentence-3)
[*Example [5](#class.conv.fct-example-5)*: struct X {operator int();};
struct Y : X {operator char();};
void f(Y& a) {if (a) { // error: ambiguous between X::operator int() and Y::operator char()}} — *end example*]
— *end note*]
[7](#class.conv.fct-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2709)
Conversion functions can be virtual[.](#class.conv.fct-7.sentence-1)
[8](#class.conv.fct-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2713)
A conversion function template shall not have a
deduced return type ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7Placeholder type specifiers"))[.](#class.conv.fct-8.sentence-1)
[*Example [6](#class.conv.fct-example-6)*: struct S {operator auto() const { return 10; } // OKtemplate<class T>operator auto() const { return 1.2; } // error: conversion function template}; — *end example*]
### [11.4.9](#class.static) Static members [[class.static]](class.static)
#### [11.4.9.1](#class.static.general) General [[class.static.general]](class.static.general)
[1](#class.static.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2732)
A static member s of class X may be referred to
using the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") expression X::s; it is not
necessary to use the class member access syntax ([[expr.ref]](expr.ref "7.6.1.5Class member access")) to
refer to a static member[.](#class.static.general-1.sentence-1)
A static member may be
referred to using the class member access syntax, in which case the
object expression is evaluated[.](#class.static.general-1.sentence-2)
[*Example [1](#class.static.general-example-1)*: struct process {static void reschedule();};
process& g();
void f() { process::reschedule(); // OK, no object necessary g().reschedule(); // g() is called} — *end example*]
[2](#class.static.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2753)
Static members obey the usual class member access rules ([[class.access]](class.access "11.8Member access control"))[.](#class.static.general-2.sentence-1)
When used in the declaration of a class
member, the static specifier shall only be used in the member
declarations that appear within the [*member-specification*](#nt:member-specification "11.4.1General[class.mem.general]") of
the class definition[.](#class.static.general-2.sentence-2)
[*Note [1](#class.static.general-note-1)*:
It cannot be specified in member declarations that appear in namespace scope[.](#class.static.general-2.sentence-3)
— *end note*]
#### [11.4.9.2](#class.static.mfct) Static member functions [[class.static.mfct]](class.static.mfct)
[1](#class.static.mfct-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2766)
[*Note [1](#class.static.mfct-note-1)*:
The rules described in [[class.mfct]](#class.mfct "11.4.2Member functions") apply to static member
functions[.](#class.static.mfct-1.sentence-1)
— *end note*]
[2](#class.static.mfct-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2772)
[*Note [2](#class.static.mfct-note-2)*:
A static member function does not have a this pointer ([[expr.prim.this]](expr.prim.this "7.5.3This"))[.](#class.static.mfct-2.sentence-1)
A static member function cannot be qualified with const,volatile, or virtual ([[dcl.fct]](dcl.fct "9.3.4.6Functions"))[.](#class.static.mfct-2.sentence-2)
— *end note*]
#### [11.4.9.3](#class.static.data) Static data members [[class.static.data]](class.static.data)
[1](#class.static.data-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2783)
A static data member is not part of the subobjects of a class[.](#class.static.data-1.sentence-1)
If a
static data member is declared thread_local there is one copy of
the member per thread[.](#class.static.data-1.sentence-2)
If a static data member is not declaredthread_local there is one copy of the data member that is shared by all
the objects of the class[.](#class.static.data-1.sentence-3)
[2](#class.static.data-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2790)
A static data member shall not be mutable ([[dcl.stc]](dcl.stc "9.2.2Storage class specifiers"))[.](#class.static.data-2.sentence-1)
A static data member shall not be a direct member ([class.mem])
of an unnamed ([[class.pre]](class.pre "11.1Preamble")) or local ([[class.local]](class.local "11.6Local class declarations")) class or
of a (possibly indirectly) nested class ([[class.nest]](#class.nest "11.4.12Nested class declarations")) thereof[.](#class.static.data-2.sentence-2)
[3](#class.static.data-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2796)
The declaration of a non-inline
static data member in its class definition
is not a definition and may be of an incomplete type other thancv void[.](#class.static.data-3.sentence-1)
[*Note [1](#class.static.data-note-1)*:
The [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") in the definition of a
static data member is in the scope of its
class ([[basic.scope.class]](basic.scope.class "6.4.7Class scope"))[.](#class.static.data-3.sentence-2)
— *end note*]
[*Example [1](#class.static.data-example-1)*: class process {static process* run_chain; static process* running;};
process* process::running = get_main();
process* process::run_chain = running;
The definition of the static data member run_chain of classprocess inhabits the global scope; the notationprocess::run_chain indicates that the member run_chain is a member of class process and in the scope of classprocess[.](#class.static.data-3.sentence-3)
In the static data member definition, the[*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") expression refers to the static data
member running of class process[.](#class.static.data-3.sentence-4)
— *end example*]
[*Note [2](#class.static.data-note-2)*:
Once the static data member has been defined, it exists even if
no objects of its class have been created[.](#class.static.data-3.sentence-5)
[*Example [2](#class.static.data-example-2)*:
In the example above, run_chain and running exist even
if no objects of class process are created by the program[.](#class.static.data-3.sentence-6)
— *end example*]
The initialization and destruction of static data members is described in[[basic.start.static]](basic.start.static "6.10.3.2Static initialization"), [[basic.start.dynamic]](basic.start.dynamic "6.10.3.3Dynamic initialization of non-block variables"), and [[basic.start.term]](basic.start.term "6.10.3.4Termination")[.](#class.static.data-3.sentence-7)
— *end note*]
[4](#class.static.data-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2840)
If a non-volatile non-inline const static data member is
of integral or enumeration type,
its declaration in the class definition can specify a[*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]") in which every[*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1General[dcl.init.general]") that is an [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19Assignment and compound assignment operators[expr.assign]") is a constant expression ([[expr.const]](expr.const "7.7Constant expressions"))[.](#class.static.data-4.sentence-1)
The member shall still be defined in a namespace scope if
it is odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule")) in the program and the
namespace scope definition shall not contain an [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]")[.](#class.static.data-4.sentence-2)
The declaration of an inline static data member (which is a definition)
may specify a [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")[.](#class.static.data-4.sentence-3)
If the
member is declared with the constexpr specifier, it may be
redeclared in namespace scope with no initializer (this usage is
deprecated; see [[depr.static.constexpr]](depr.static.constexpr "D.7Redeclaration of static constexpr data members"))[.](#class.static.data-4.sentence-4)
Declarations of other
static data members shall not specify a [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")[.](#class.static.data-4.sentence-5)
[5](#class.static.data-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2857)
[*Note [3](#class.static.data-note-3)*:
There is exactly one definition of a static data member
that is odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule")) in a valid program[.](#class.static.data-5.sentence-1)
— *end note*]
[6](#class.static.data-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2863)
[*Note [4](#class.static.data-note-4)*:
Static data members of a class in namespace scope have the linkage of the name of the class ([[basic.link]](basic.link "6.7Program and linkage"))[.](#class.static.data-6.sentence-1)
— *end note*]
### [11.4.10](#class.bit) Bit-fields [[class.bit]](class.bit)
[1](#class.bit-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2871)
A [*member-declarator*](#nt:member-declarator "11.4.1General[class.mem.general]") of the form
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt : [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]")opt
specifies a bit-field[.](#class.bit-1.sentence-1)
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") appertains
to the entity being declared[.](#class.bit-1.sentence-2)
A bit-field shall not be a static member[.](#class.bit-1.sentence-3)
A bit-field shall have integral or (possibly cv-qualified) enumeration type;
the bit-field semantic property is not part of the type of the class member[.](#class.bit-1.sentence-4)
The [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") shall be an integral constant expression
with a value greater than or equal to zero and
is called the [*width*](simd.general#def:width "29.10.1General[simd.general]") of the bit-field[.](#class.bit-1.sentence-5)
If the width of a bit-field is larger than
the width of the bit-field's type
(or, in case of an enumeration type, of its underlying type),
the extra bits are padding bits ([[basic.types.general]](basic.types.general#term.padding.bits "6.9.1General"))[.](#class.bit-1.sentence-6)
Allocation of bit-fields within a class object isimplementation-defined[.](#class.bit-1.sentence-7)
Alignment of bit-fields is implementation-defined[.](#class.bit-1.sentence-8)
Bit-fields are packed into some addressable allocation unit[.](#class.bit-1.sentence-9)
[*Note [1](#class.bit-note-1)*:
Bit-fields straddle allocation units on some machines and not on others[.](#class.bit-1.sentence-10)
Bit-fields are assigned right-to-left on some machines, left-to-right on
others[.](#class.bit-1.sentence-11)
— *end note*]
[2](#class.bit-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2905)
A declaration for a bit-field that omits the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") declares an [*unnamed bit-field*](#def:bit-field,unnamed "11.4.10Bit-fields[class.bit]")[.](#class.bit-2.sentence-1)
Unnamed bit-fields are not
members and cannot be initialized[.](#class.bit-2.sentence-2)
An unnamed bit-field shall not be declared with a cv-qualified type[.](#class.bit-2.sentence-3)
[*Note [2](#class.bit-note-2)*:
An unnamed bit-field is useful for padding to conform to
externally-imposed layouts[.](#class.bit-2.sentence-4)
— *end note*]
As a special case, an unnamed bit-field with a width of zero specifies
alignment of the next bit-field at an allocation unit boundary[.](#class.bit-2.sentence-5)
Only
when declaring an unnamed bit-field may the width be zero[.](#class.bit-2.sentence-6)
[3](#class.bit-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2920)
The address-of operator & shall not be applied to a bit-field,
so there are no pointers to bit-fields[.](#class.bit-3.sentence-1)
A non-const reference shall not bind to a bit-field ([[dcl.init.ref]](dcl.init.ref "9.5.4References"))[.](#class.bit-3.sentence-2)
[*Note [3](#class.bit-note-3)*:
If the initializer for a reference of type const T& is
an lvalue that refers to a bit-field, the reference is bound to a
temporary initialized to hold the value of the bit-field; the reference
is not bound to the bit-field directly[.](#class.bit-3.sentence-3)
See [[dcl.init.ref]](dcl.init.ref "9.5.4References")[.](#class.bit-3.sentence-4)
— *end note*]
[4](#class.bit-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2935)
If a value of integral type (other than bool) is stored
into a bit-field of width N and the value would be representable
in a hypothetical signed or unsigned integer type
with width N and the same signedness as the bit-field's type,
the original value and the value of the bit-field compare equal[.](#class.bit-4.sentence-1)
If the value true or false is stored into a bit-field of
type bool of any size (including a one bit bit-field), the
original bool value and the value of the bit-field compare
equal[.](#class.bit-4.sentence-2)
If a value of an enumeration type is stored into a bit-field of the
same type and the width is large
enough to hold all the values of that enumeration type ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")),
the original value and the value of the bit-field compare equal[.](#class.bit-4.sentence-3)
[*Example [1](#class.bit-example-1)*: enum BOOL { FALSE=0, TRUE=1 };struct A { BOOL b:1;};
A a;void f() { a.b = TRUE; if (a.b == TRUE) // yields true{ /* ... */ }} — *end example*]
### [11.4.11](#class.free) Allocation and deallocation functions [[class.free]](class.free)
[1](#class.free-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2966)
Any allocation function for a classT is a static member (even if not explicitly declaredstatic)[.](#class.free-1.sentence-1)
[2](#class.free-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2974)
[*Example [1](#class.free-example-1)*: class Arena;struct B {void* operator new(std::size_t, Arena*);};struct D1 : B {};
Arena* ap;void foo(int i) {new (ap) D1; // calls B::operator new(std::size_t, Arena*)new D1[i]; // calls ::operator new[](std::size_t)new D1; // error: ::operator new(std::size_t) hidden} — *end example*]
[3](#class.free-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2993)
Any deallocation function for a classX is a static member (even if not explicitly declaredstatic)[.](#class.free-3.sentence-1)
[*Example [2](#class.free-example-2)*: class X {void operator delete(void*); void operator delete[](void*, std::size_t);};
class Y {void operator delete(void*, std::size_t); void operator delete[](void*);}; — *end example*]
[4](#class.free-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3014)
Since member allocation and deallocation functions arestatic they cannot be virtual[.](#class.free-4.sentence-1)
[*Note [1](#class.free-note-1)*:
However, when the[*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit type conversion (cast notation)[expr.cast]") of a[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]") refers to an object of class type with a virtual destructor,
because the deallocation function is chosen by the destructor
of the dynamic type of the object, the effect is the same in that case[.](#class.free-4.sentence-2)
[*Example [3](#class.free-example-3)*: struct B {virtual ~B(); void operator delete(void*, std::size_t);};
struct D : B {void operator delete(void*);};
struct E : B {void log_deletion(); void operator delete(E *p, std::destroying_delete_t) { p->log_deletion();
p->~E(); ::operator delete(p); }};
void f() { B* bp = new D; delete bp; // 1: uses D::operator delete(void*) bp = new E; delete bp; // 2: uses E::operator delete(E*, std::destroying_delete_t)}
Here, storage for the object of classD is deallocated byD::operator delete(),
and
the object of class E is destroyed
and its storage is deallocated
by E::operator delete(),
due to the virtual destructor[.](#class.free-4.sentence-3)
— *end example*]
— *end note*]
[*Note [2](#class.free-note-2)*:
Virtual destructors have no effect on the deallocation function actually
called when the[*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit type conversion (cast notation)[expr.cast]") of a[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]") refers to an array of objects of class type[.](#class.free-4.sentence-4)
[*Example [4](#class.free-example-4)*: struct B {virtual ~B(); void operator delete[](void*, std::size_t);};
struct D : B {void operator delete[](void*, std::size_t);};
void f(int i) { D* dp = new D[i]; delete [] dp; // uses D::operator delete[](void*, std::size_t) B* bp = new D[i]; delete[] bp; // undefined behavior} — *end example*]
— *end note*]
[5](#class.free-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3092)
Access to the deallocation function is checked statically,
even if a different one is actually executed[.](#class.free-5.sentence-1)
[*Example [5](#class.free-example-5)*:
For the call on line “// 1” above,
ifB::operator delete() had been private, the delete expression would have been ill-formed[.](#class.free-5.sentence-2)
— *end example*]
[6](#class.free-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3102)
[*Note [3](#class.free-note-3)*:
If a deallocation function has no explicit [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5Exception specifications[except.spec]"), it
has a non-throwing exception specification ([[except.spec]](except.spec "14.5Exception specifications"))[.](#class.free-6.sentence-1)
— *end note*]
### [11.4.12](#class.nest) Nested class declarations [[class.nest]](class.nest)
[1](#class.nest-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3111)
A class can be declared within another class[.](#class.nest-1.sentence-1)
A class declared within
another is called a [*nested class*](#def:class,nested "11.4.12Nested class declarations[class.nest]")[.](#class.nest-1.sentence-2)
[*Note [1](#class.nest-note-1)*:
See [[expr.prim.id]](expr.prim.id "7.5.5Names") for restrictions on the use of non-static data
members and non-static member functions[.](#class.nest-1.sentence-3)
— *end note*]
[*Example [1](#class.nest-example-1)*: int x;int y;
struct enclose {int x; static int s; struct inner {void f(int i) {int a = sizeof(x); // OK, operand of sizeof is an unevaluated operand x = i; // error: assign to enclose::x s = i; // OK, assign to enclose::s::x = i; // OK, assign to global x y = i; // OK, assign to global y}void g(enclose* p, int i) { p->x = i; // OK, assign to enclose::x}};};
inner* p = 0; // error: inner not found — *end example*]
[2](#class.nest-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3146)
[*Note [2](#class.nest-note-2)*:
Nested classes can be defined
either in the enclosing class or in an enclosing namespace;
member functions and static data members of a nested class can be
defined either in the nested class or in an enclosing namespace scope[.](#class.nest-2.sentence-1)
[*Example [2](#class.nest-example-2)*: struct enclose {struct inner {static int x; void f(int i); };};
int enclose::inner::x = 1;
void enclose::inner::f(int i) { /* ... */ }class E {class I1; // forward declaration of nested classclass I2; class I1 { }; // definition of nested class};class E::I2 { }; // definition of nested class — *end example*]
— *end note*]
[3](#class.nest-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3175)
A friend function ([[class.friend]](class.friend "11.8.4Friends")) defined
within a nested class has no special access rights to
members of an enclosing class[.](#class.nest-3.sentence-1)