A class is a type. Its name becomes a class-name ([class.name]) within its scope.
class-name: identifier simple-template-id
Class-specifiers and elaborated-type-specifiers are used to make class-names. An object of a class consists of a (possibly empty) sequence of members and base class objects.
class-specifier: class-head { member-specificationopt }
class-head: class-key attribute-specifier-seqopt class-head-name class-virt-specifieropt base-clauseopt class-key attribute-specifier-seqopt base-clauseopt
class-head-name: nested-name-specifieropt class-name
class-virt-specifier: final
class-key: class struct union
A class-specifier whose class-head omits the class-head-name defines an unnamed class. [ Note: An unnamed class thus can't be final. — end note ]
A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name. A class-specifier is commonly referred to as a class definition. A class is considered defined after the closing brace of its class-specifier has been seen even though its member functions are in general not yet defined. The optional attribute-specifier-seq appertains to the class; the attributes in the attribute-specifier-seq are thereafter considered attributes of the class whenever it is named.
If a class is marked with the class-virt-specifier final and it appears as a class-or-decltype in a base-clause, the program is ill-formed. Whenever a class-key is followed by a class-head-name, the identifier final, and a colon or left brace, final is interpreted as a class-virt-specifier. [ Example:
struct A; struct A final {}; // OK: definition of struct A, // not value-initialization of variable final struct X { struct C { constexpr operator int() { return 5; } }; struct B final : C{}; // OK: definition of nested class B, // not declaration of a bit-field member final };
— end example ]
Complete objects and member subobjects of class type shall have nonzero size.107 [ Note: Class objects can be assigned, passed as arguments to functions, and returned by functions (except objects of classes for which copying or moving has been restricted; see [class.copy]). Other plausible operators, such as equality comparison, can be defined by the user; see [over.oper]. — end note ]
A union is a class defined with the class-key union; it holds at most one data member at a time ([class.union]). [ Note: Aggregates of class type are described in [dcl.init.aggr]. — end note ]
A trivially copyable class is a class:
where each copy constructor, move constructor, copy assignment operator, and move assignment operator ([class.copy], [over.ass]) is either deleted or trivial,
that has at least one non-deleted copy constructor, move constructor, copy assignment operator, or move assignment operator, and
that has a trivial, non-deleted destructor.
A trivial class is a class that is trivially copyable and has one or more default constructors, all of which are either trivial or deleted and at least one of which is not deleted. [ Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes. — end note ]
A class S is a standard-layout class if it:
has no non-static data members of type non-standard-layout class (or array of such types) or reference,
has no virtual functions and no virtual base classes,
has the same access control for all non-static data members,
has no non-standard-layout base classes,
has at most one base class subobject of any given type,
has all non-static data members and bit-fields in the class and its base classes first declared in the same class, and
has no element of the set M(S) of types (defined below) as a base class.108
M(X) is defined as follows:
If X is a non-union class type with no (possibly inherited) non-static data members, the set M(X) is empty.
If X is a non-union class type whose first non-static data member has type X0 (where said member may be an anonymous union), the set M(X) consists of X0 and the elements of M(X0).
If X is a union type, the set M(X) is the union of all M(Ui) and the set containing all Ui, where each Ui is the type of the ith non-static data member of X.
If X is an array type with element type Xe, the set M(X) consists of Xe and the elements of M(Xe).
If X is a non-class, non-array type, the set M(X) is empty.
[ Note: M(X) is the set of the types of all non-base-class subobjects that are guaranteed in a standard-layout class to be at a zero offset in X. — end note ]
[ Example:
struct B { int i; }; // standard-layout class struct C : B { }; // standard-layout class struct D : C { }; // standard-layout class struct E : D { char : 4; }; // not a standard-layout class struct Q {}; struct S : Q { }; struct T : Q { }; struct U : S, T { }; // not a standard-layout class
— end example ]
A standard-layout struct is a standard-layout class defined with the class-key struct or the class-key class. A standard-layout union is a standard-layout class defined with the class-key union.
[ Note: Standard-layout classes are useful for communicating with code written in other programming languages. Their layout is specified in [class.mem]. — end note ]
A POD struct109 is a non-union class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). Similarly, a POD union is a union that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). A POD class is a class that is either a POD struct or a POD union.
[ Example:
struct N { // neither trivial nor standard-layout int i; int j; virtual ~N(); }; struct T { // trivial but not standard-layout int i; private: int j; }; struct SL { // standard-layout but not trivial int i; int j; ~SL(); }; struct POD { // both trivial and standard-layout int i; int j; };
— end example ]
If a class-head-name contains a nested-name-specifier, the class-specifier shall refer to a class that was previously declared directly in the class or namespace to which the nested-name-specifier refers, or in an element of the inline namespace set of that namespace (i.e., not merely inherited or introduced by a using-declaration), and the class-specifier shall appear in a namespace enclosing the previous declaration. In such cases, the nested-name-specifier of the class-head-name of the definition shall not begin with a decltype-specifier.
Base class subobjects are not so constrained.
This ensures that two subobjects that have the same class type and that belong to the same most derived object are not allocated at the same address ([expr.eq]).
The acronym POD stands for “plain old data”.
A class definition introduces a new type. [ Example:
struct X { int a; }; struct Y { int a; }; X a1; Y a2; int a3;
declares three variables of three different types. This implies that
a1 = a2; // error: Y assigned to X a1 = a3; // error: int assigned to X
are type mismatches, and that
int f(X); int f(Y);
declare an overloaded function f() and not simply a single function f() twice. For the same reason,
struct S { int a; };
struct S { int a; }; // error, double definition
is ill-formed because it defines S twice. — end example ]
A class declaration introduces the class name into the scope where it is declared and hides any class, variable, function, or other declaration of that name in an enclosing scope. If a class name is declared in a scope where a variable, function, or enumerator of the same name is also declared, then when both declarations are in scope, the class can be referred to only using an elaborated-type-specifier ([basic.lookup.elab]). [ Example:
struct stat { // ... }; stat gstat; // use plain stat to define variable int stat(struct stat*); // redeclare stat as function void f() { struct stat* ps; // struct prefix needed to name struct stat stat(ps); // call stat() }
— end example ] A declaration consisting solely of class-key identifier; is either a redeclaration of the name in the current scope or a forward declaration of the identifier as a class name. It introduces the class name into the current scope. [ Example:
struct s { int a; }; void g() { struct s; // hide global struct s with a block-scope declaration s* p; // refer to local struct s struct s { char* p; }; // define local struct s struct s; // redeclaration, has no effect }
— end example ] [ Note: Such declarations allow definition of classes that refer to each other. [ Example:
class Vector; class Matrix { // ... friend Vector operator*(const Matrix&, const Vector&); }; class Vector { // ... friend Vector operator*(const Matrix&, const Vector&); };
Declaration of friends is described in [class.friend], operator functions in [over.oper]. — end example ] — end note ]
[ Note: An elaborated-type-specifier can also be used as a type-specifier as part of a declaration. It differs from a class declaration in that if a class of the elaborated name is in scope the elaborated name will refer to it. — end note ] [ Example:
struct s { int a; }; void g(int s) { struct s* p = new struct s; // global s p->a = s; // parameter s }
— end example ]
[ Note: The declaration of a class name takes effect immediately after the identifier is seen in the class definition or elaborated-type-specifier. For example,
class A * A;
first specifies A to be the name of a class and then redefines it as the name of a pointer to an object of that class. This means that the elaborated form class A must be used to refer to the class. Such artistry with names can be confusing and is best avoided. — end note ]
A typedef-name that names a class type, or a cv-qualified version thereof, is also a class-name. If a typedef-name that names a cv-qualified class type is used where a class-name is required, the cv-qualifiers are ignored. A typedef-name shall not be used as the identifier in a class-head.
member-specification: member-declaration member-specificationopt access-specifier : member-specificationopt
member-declaration: attribute-specifier-seqopt decl-specifier-seqopt member-declarator-listopt ; function-definition using-declaration static_assert-declaration template-declaration deduction-guide alias-declaration empty-declaration
member-declarator-list: member-declarator member-declarator-list , member-declarator
member-declarator: declarator virt-specifier-seqopt pure-specifieropt declarator brace-or-equal-initializeropt identifieropt attribute-specifier-seqopt : constant-expression
virt-specifier-seq: virt-specifier virt-specifier-seq virt-specifier
virt-specifier: override final
pure-specifier: = 0
The member-specification in a class definition declares the full set of members of the class; no member can be added elsewhere. A direct member of a class X is a member of X that was first declared within the member-specification of X, including anonymous union objects ([class.union.anon]) and direct members thereof. Members of a class are data members, member functions, nested types, enumerators, and member templates and specializations thereof. [ Note: A specialization of a static data member template is a static data member. A specialization of a member function template is a member function. A specialization of a member class template is a nested class. — end note ]
A member-declaration does not declare new members of the class if it is
For any other member-declaration, each declared entity that is not an unnamed bit-field is a member of the class, and each such member-declaration shall either declare at least one member name of the class or declare at least one unnamed bit-field.
A data member is a non-function member introduced by a member-declarator. A member function is a member that is a function. Nested types are classes ([class.name], [class.nest]) and enumerations declared in the class and arbitrary types declared as members by use of a typedef declaration or alias-declaration. The enumerators of an unscoped enumeration defined in the class are members of the class.
A data member or member function may be declared static in its member-declaration, in which case it is a static member (see [class.static]) (a static data member ([class.static.data]) or static member function ([class.static.mfct]), respectively) of the class. Any other data member or member function is a non-static member (a non-static data member or non-static member function ([class.mfct.non-static]), respectively). [ Note: A non-static data member of non-reference type is a member subobject of a class object ([intro.object]). — end note ]
A member shall not be declared twice in the member-specification, except that
a nested class or member class template can be declared and then later defined, and
an enumeration can be introduced with an opaque-enum-declaration and later redeclared with an enum-specifier.
[ Note: A single name can denote several member functions provided their types are sufficiently different (Clause [over]). — end note ]
A class is considered a completely-defined object type ([basic.types]) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, noexcept-specifiers, and default member initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.
In a member-declarator, an = immediately following the declarator is interpreted as introducing a pure-specifier if the declarator-id has function type, otherwise it is interpreted as introducing a brace-or-equal-initializer. [ Example:
struct S { using T = void(); T * p = 0; // OK: brace-or-equal-initializer virtual T f = 0; // OK: pure-specifier };
— end example ]
A brace-or-equal-initializer shall appear only in the declaration of a data member. (For static data members, see [class.static.data]; for non-static data members, see [class.base.init] and [dcl.init.aggr]). A brace-or-equal-initializer for a non-static data member specifies a default member initializer 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.
A member shall not be declared with the extern storage-class-specifier. Within a class definition, a member shall not be declared with the thread_local storage-class-specifier unless also declared static.
The decl-specifier-seq may be omitted in constructor, destructor, and conversion function declarations only; when declaring another kind of member the decl-specifier-seq shall contain a type-specifier that is not a cv-qualifier. The member-declarator-list can be omitted only after a class-specifier or an enum-specifier or in a friend declaration. A pure-specifier shall be used only in the declaration of a virtual function that is not a friend declaration.
The optional attribute-specifier-seq in a member-declaration appertains to each of the entities declared by the member-declarators; it shall not appear if the optional member-declarator-list is omitted.
A virt-specifier-seq shall contain at most one of each virt-specifier. A virt-specifier-seq shall appear only in the declaration of a virtual member function.
Non-static data members shall not have incomplete types. In particular, a class C shall not contain a non-static member of class C, but it can contain a pointer or reference to an object of class C.
[ Note: See [expr.prim] for restrictions on the use of non-static data members and non-static member functions. — end note ]
[ Note: 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. There are no special member function types or data member types. — end note ]
[ Example: A simple example of a class definition is
struct 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. Once this definition has been given, the declaration
tnode s, *sp;
declares s to be a tnode and sp to be a pointer to a tnode. 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 object s; and s.right->tword[0] refers to the initial character of the tword member of the right subtree of s. — end example ]
Non-static data members of a (non-union) class with the same access control are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified. Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions and virtual base classes.
If T is the name of a class, then each of the following shall have a name different from T:
every static data member of class T;
every member function of class T [ Note: This restriction does not apply to constructors, which do not have names — end note ] ;
every member of class T that is itself a type;
every member template of class T;
every enumerator of every member of class T that is an unscoped enumerated type; and
every member of every anonymous union that is a member of class T.
In addition, if class T has a user-declared constructor, every non-static data member of class T shall have a name different from T.
The common initial sequence of two standard-layout struct 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 corresponding entities have layout-compatible types and either neither entity is a bit-field or both are bit-fields with the same width. [ Example:
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. The common initial sequence of A and C and of A and D comprises the first member in each case. The common initial sequence of A and E is empty. — end example ]
Two standard-layout struct types are layout-compatible classes if their common initial sequence comprises all members and bit-fields of both classes ([basic.types]).
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.
In a standard-layout union with an active member 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. [ Example:
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 t1 return u.t2.c; // OK, as if u.t1.a were nominated }
— end example ] [ Note: Reading a volatile object through a non-volatile glvalue has undefined behavior ([dcl.type.cv]). — end note ]
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. Otherwise, its address is the same as the address of its first base class subobject (if any). [ Note: There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. — end note ] [ Note: The object and its first subobject are pointer-interconvertible ([basic.compound], [expr.static.cast]). — end note ]
A member function may be defined in its class definition, in which case it is an inline member function, or it may be defined outside of its class definition if it has already been declared but not defined in its class definition. A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition. Except for member function definitions that appear outside of a class definition, and except for explicit specializations of member functions of class templates and member function templates ([temp.spec]) appearing outside of the class definition, a member function shall not be redeclared.
An inline member function (whether static or non-static) may also be defined outside of its class definition provided either its declaration in the class definition or its definition outside of the class definition declares the function as inline or constexpr. [ Note: Member functions of a class in namespace scope have the linkage of that class. Member functions of a local class have no linkage. See [basic.link]. — end note ]
[ Note: There can be at most one definition of a non-inline member function in a program. There may be more than one inline member function definition in a program. See [basic.def.odr] and [dcl.inline]. — end note ]
If the definition of a member function is lexically outside its class definition, the member function name shall be qualified by its class name using the :: operator. [ Note: A name used in a member function definition (that is, in the parameter-declaration-clause including the default arguments or in the member function body) is looked up as described in [basic.lookup]. — end note ] [ Example:
struct X { typedef int T; static T count; void f(T); }; void X::f(T t = count) { }
The member function f of class X is defined in global scope; the notation X::f specifies that the function f is a member of class X and in the scope of class X. 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. — end example ]
[ Note: A static local variable or local type in a member function always refers to the same entity, whether or not the member function is inline. — end note ]
Member functions of a local class shall be defined inline in their class definition, if they are defined at all.
[ Note: A member function can be declared (but not defined) using a typedef for a function type. The resulting member function has exactly the same type as it would have if the function declarator were provided explicitly, see [dcl.fct]. For example,
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;
Also see [temp.arg]. — end note ]
A non-static member function may be called for an object of its class type, or for an object of a class derived from its class type, using the class member access syntax ([over.match.call]). A non-static member function may also be called directly using the function call syntax ([expr.call], [over.match.call]) from within the body of a member function of its class or of a class derived from its class.
If a non-static member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined.
When an id-expression that is not part of a class member access syntax and not used to form a pointer to member ([expr.unary.op]) is used in a member of class X in a context where this can be used, if name lookup resolves the name in the id-expression to a non-static non-type member of some class C, and if either the id-expression is potentially evaluated or C is X or a base class of X, the id-expression is transformed into a class member access expression using (*this) as the postfix-expression to the left of the . operator. [ Note: If C is not X or a base class of X, the class member access expression is ill-formed. — end note ] Similarly during name lookup, when an unqualified-id used in the definition of a member function for class X resolves to a static member, an enumerator or a nested type of class X or of a base class of X, the unqualified-id is transformed into a qualified-id in which the nested-name-specifier names the class of the member function. These transformations do not apply in the template definition context ([temp.dep.type]). [ Example:
struct tnode { char tword[20]; int count; tnode* left; tnode* right; void set(const char*, tnode* l, tnode* r); }; void tnode::set(const char* w, tnode* l, tnode* r) { count = strlen(w)+1; if (sizeof(tword)<=count) perror("tnode string too long"); strcpy(tword,w); left = l; right = r; } void f(tnode n1, tnode n2) { n1.set("abc",&n2,0); n2.set("def",0,0); }
In the body of the member function tnode::set, the member names tword, count, left, and right refer to members of the object for which the function is called. Thus, in the call n1.set("abc",&n2,0), tword refers to n1.tword, and in the call n2.set("def",0,0), it refers to n2.tword. The functions strlen, perror, and strcpy are not members of the class tnode and should be declared elsewhere.110 — end example ]
A non-static member function may be declared const, volatile, or const volatile. These cv-qualifiers affect the type of the this pointer. They also affect the function type of the member function; a member function declared const is a const member function, a member function declared volatile is a volatile member function and a member function declared const volatile is a const volatile member function. [ Example:
struct X { void g() const; void h() const volatile; };
X::g is a const member function and X::h is a const volatile member function. — end example ]
A non-static member function may be declared with a ref-qualifier ([dcl.fct]); see [over.match.funcs].
A non-static member function may be declared virtual ([class.virtual]) or pure virtual ([class.abstract]).
See, for example, <cstring> ([c.strings]).
In the body of a non-static member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called. The type of this in a member function of a class X is X*. If the member function is declared const, the type of this is const X*, if the member function is declared volatile, the type of this is volatile X*, and if the member function is declared const volatile, the type of this is const volatile X*. [ Note: Thus in a const member function, the object for which the function is called is accessed through a const access path. — end note ] [ Example:
struct s {
int a;
int f() const;
int g() { return a++; }
int h() const { return a++; } // error
};
int s::f() const { return a; }
The a++ in the body of s::h is ill-formed because it tries to modify (a part of) the object for which s::h() is called. This is not allowed in a const member function because this is a pointer to const; that is, *this has const type. — end example ]
Similarly, volatile semantics apply in volatile member functions when accessing the object and its non-static data members.
A cv-qualified member function can be called on an object-expression only if the object-expression is as cv-qualified or less-cv-qualified than the member function. [ Example:
void k(s& x, const s& y) {
x.f();
x.g();
y.f();
y.g(); // error
}
The call y.g() is ill-formed because y is const and s::g() is a non-const member function, that is, s::g() is less-qualified than the object-expression y. — end example ]
Constructors and destructors shall not be declared const, volatile or const volatile. [ Note: However, these functions can be invoked to create and destroy objects with cv-qualified types, see [class.ctor] and [class.dtor]. — end note ]
A static member s of class X may be referred to using the qualified-id expression X::s; it is not necessary to use the class member access syntax to refer to a static member. A static member may be referred to using the class member access syntax, in which case the object expression is evaluated. [ Example:
struct process { static void reschedule(); }; process& g(); void f() { process::reschedule(); // OK: no object necessary g().reschedule(); // g() is called }
— end example ]
A static member may be referred to directly in the scope of its class or in the scope of a class derived from its class; in this case, the static member is referred to as if a qualified-id expression was used, with the nested-name-specifier of the qualified-id naming the class scope from which the static member is referenced. [ Example:
int g();
struct X {
static int g();
};
struct Y : X {
static int i;
};
int Y::i = g(); // equivalent to Y::g();
— end example ]
If an unqualified-id is used in the definition of a static member following the member's declarator-id, and name lookup finds that the unqualified-id refers to a static member, enumerator, or nested type of the member's class (or of a base class of the member's class), the unqualified-id is transformed into a qualified-id expression in which the nested-name-specifier names the class scope from which the member is referenced. [ Note: See [expr.prim] for restrictions on the use of non-static data members and non-static member functions. — end note ]
Static members obey the usual class member access rules. 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 of the class definition. [ Note: It cannot be specified in member declarations that appear in namespace scope. — end note ]
[ Note: A static member function does not have a this pointer. — end note ] A static member function shall not be virtual. There shall not be a static and a non-static member function with the same name and the same parameter types ([over.load]). A static member function shall not be declared const, volatile, or const volatile.
A static data member is not part of the subobjects of a class. If a static data member is declared thread_local there is one copy of the member per thread. If a static data member is not declared thread_local there is one copy of the data member that is shared by all the objects of the class.
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 than cv void. The definition for a static data member that is not defined inline in the class definition shall appear in a namespace scope enclosing the member's class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator. The initializer expression in the definition of a static data member is in the scope of its class ([basic.scope.class]). [ Example:
class process { static process* run_chain; static process* running; }; process* process::running = get_main(); process* process::run_chain = running;
The static data member run_chain of class process is defined in global scope; the notation process::run_chain specifies that the member run_chain is a member of class process and in the scope of class process. In the static data member definition, the initializer expression refers to the static data member running of class process. — end example ]
[ Note: Once the static data member has been defined, it exists even if no objects of its class have been created. [ Example: In the example above, run_chain and running exist even if no objects of class process are created by the program. — end example ] — end note ]
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 in which every initializer-clause that is an assignment-expression is a constant expression ([expr.const]). The member shall still be defined in a namespace scope if it is odr-used in the program and the namespace scope definition shall not contain an initializer. An inline static data member may be defined in the class definition and may specify a brace-or-equal-initializer. 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]). Declarations of other static data members shall not specify a brace-or-equal-initializer.
[ Note: There shall be exactly one definition of a static data member that is odr-used in a program; no diagnostic is required. — end note ] Unnamed classes and classes contained directly or indirectly within unnamed classes shall not contain static data members.
[ Note: Static data members of a class in namespace scope have the linkage of that class. A local class cannot have static data members. — end note ]
Static data members are initialized and destroyed exactly like non-local variables ([basic.start.static], [basic.start.dynamic], [basic.start.term]).
A member-declarator of the form
identifieropt attribute-specifier-seqopt : constant-expression
specifies a bit-field; its length is set off from the bit-field name by a colon. The optional attribute-specifier-seq appertains to the entity being declared. The bit-field attribute is not part of the type of the class member. The constant-expression shall be an integral constant expression with a value greater than or equal to zero. The value of the integral constant expression may be larger than the number of bits in the object representation of the bit-field's type; in such cases the extra bits are used as padding bits and do not participate in the value representation of the bit-field. Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [ Note: Bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others. — end note ]
A declaration for a bit-field that omits the identifier declares an unnamed bit-field. Unnamed bit-fields are not members and cannot be initialized. [ Note: An unnamed bit-field is useful for padding to conform to externally-imposed layouts. — 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. Only when declaring an unnamed bit-field may the value of the constant-expression be equal to zero.
A bit-field shall not be a static member. A bit-field shall have integral or enumeration type ([basic.fundamental]). A bool value can successfully be stored in a bit-field of any nonzero size. The address-of operator & shall not be applied to a bit-field, so there are no pointers to bit-fields. A non-const reference shall not be bound to a bit-field ([dcl.init.ref]). [ Note: 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. See [dcl.init.ref]. — end note ]
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 shall compare equal. If the value of an enumerator is stored into a bit-field of the same enumeration type and the number of bits in the bit-field is large enough to hold all the values of that enumeration type, the original enumerator value and the value of the bit-field shall compare equal. [ Example:
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 ]
A class can be declared within another class. A class declared within another is called a nested class. The name of a nested class is local to its enclosing class. The nested class is in the scope of its enclosing class. [ Note: See [expr.prim] for restrictions on the use of non-static data members and non-static member functions. — end note ]
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 in scope
— end example ]
Member functions and static data members of a nested class can be defined in a namespace scope enclosing the definition of their class. [ Example:
struct enclose {
struct inner {
static int x;
void f(int i);
};
};
int enclose::inner::x = 1;
void enclose::inner::f(int i) { /* ... */ }
— end example ]
If class X is defined in a namespace scope, a nested class Y may be declared in class X and later defined in the definition of class X or be later defined in a namespace scope enclosing the definition of class X. [ Example:
class E { class I1; // forward declaration of nested class class I2; class I1 { }; // definition of nested class }; class E::I2 { }; // definition of nested class
— end example ]
Like a member function, a friend function defined within a nested class is in the lexical scope of that class; it obeys the same rules for name binding as a static member function of that class, but it has no special access rights to members of an enclosing class.
Type names obey exactly the same scope rules as other names. In particular, type names defined within a class definition cannot be used outside their class without qualification. [ Example:
struct X { typedef int I; class Y { /* ... */ }; I a; }; I b; // error Y c; // error X::Y d; // OK X::I e; // OK
— end example ]
In a union, a non-static data member is active if its name refers to an object whose lifetime has begun and has not ended. At most one of the non-static data members of an object of union type can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time. [ Note: One special guarantee is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout structs that share a common initial sequence, and if a non-static data member of an object of this standard-layout union type is active and is one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of the standard-layout struct members; see [class.mem]. — end note ]
The size of a union is sufficient to contain the largest of its non-static data members. Each non-static data member is allocated as if it were the sole member of a struct. [ Note: A union object and its non-static data members are pointer-interconvertible ([expr.static.cast]). As a consequence, all non-static data members of a union object have the same address. — end note ]
A union can have member functions (including constructors and destructors), but it shall not have virtual functions. A union shall not have base classes. A union shall not be used as a base class. If a union contains a non-static data member of reference type the program is ill-formed. [ Note: Absent default member initializers, if any non-static data member of a union has a non-trivial default constructor ([class.ctor]), copy constructor, move constructor ([class.copy]), copy assignment operator, move assignment operator, or destructor, the corresponding member function of the union must be user-provided or it will be implicitly deleted for the union. — end note ]
[ Example: Consider the following union:
union U { int i; float f; std::string s; };
Since std::string declares non-trivial versions of all of the special member functions, U will have an implicitly deleted default constructor, copy/move constructor, copy/move assignment operator, and destructor. To use U, some or all of these member functions must be user-provided. — end example ]
When the left operand of an assignment operator involves a member access expression that nominates a union member, it may begin the lifetime of that union member, as described below. For an expression E, define the set S(E) of subexpressions of E as follows:
If E is of the form A.B, S(E) contains the elements of S(A), and also contains A.B if B names a union member of a non-class, non-array type, or of a class type with a trivial default constructor that is not deleted, or an array of such types.
If E is of the form A[B] and is interpreted as a built-in array subscripting operator, S(E) is S(A) if A is of array type, S(B) if B is of array type, and empty otherwise.
Otherwise, S(E) is empty.
In an assignment expression of the form E1 = E2 that uses either the built-in assignment operator or a trivial assignment operator, for each element X of S(E1), if modification of X would have undefined behavior under [basic.life], an object of the type of X is implicitly created in the nominated storage; no initialization is performed and the beginning of its lifetime is sequenced after the value computation of the left and right operands and before the assignment. [ Note: This ends the lifetime of the previously-active member of the union, if any. — end note ] [ Example:
union A { int x; int y[4]; }; struct B { A a; }; union C { B b; int k; }; int f() { C c; // does not start lifetime of any union member c.b.a.y[3] = 4; // OK: S(c.b.a.y[3]) contains c.b and c.b.a.y; // creates objects to hold union members c.b and c.b.a.y return c.b.a.y[3]; // OK: c.b.a.y refers to newly created object (see [basic.life]) } struct X { const int a; int b; }; union Y { X x; int k; }; void g() { Y y = { { 1, 2 } }; // OK, y.x is active union member ([class.mem]) int n = y.x.a; y.k = 4; // OK: ends lifetime of y.x, y.k is active member of union y.x.b = n; // undefined behavior: y.x.b modified outside its lifetime, // S(y.x.b) is empty because X's default constructor is deleted, // so union member y.x's lifetime does not implicitly start }
— end example ]
[ Note: In general, one must use explicit destructor calls and placement new-expression to change the active member of a union. — end note ] [ Example: Consider an object u of a union type U having non-static data members m of type M and n of type N. If M has a non-trivial destructor and N has a non-trivial constructor (for instance, if they declare or inherit virtual functions), the active member of u can be safely switched from m to n using the destructor and placement new-expression as follows:
u.m.~M(); new (&u.n) N;
— end example ]
A union of the form
union { member-specification } ;
is called an anonymous union; it defines an unnamed type and an unnamed object of that type called an anonymous union object. Each member-declaration in the member-specification of an anonymous union shall either define a non-static data member or be a static_assert-declaration. [ Note: Nested types, anonymous unions, and functions cannot be declared within an anonymous union. — end note ] The names of the members of an anonymous union shall be distinct from the names of any other entity in the scope in which the anonymous union is declared. For the purpose of name lookup, after the anonymous union definition, the members of the anonymous union are considered to have been defined in the scope in which the anonymous union is declared. [ Example:
void f() { union { int a; const char* p; }; a = 1; p = "Jennifer"; }
Here a and p are used like ordinary (non-member) variables, but since they are union members they have the same address. — end example ]
Anonymous unions declared in a named namespace or in the global namespace shall be declared static. Anonymous unions declared at block scope shall be declared with any storage class allowed for a block-scope variable, or with no storage class. A storage class is not allowed in a declaration of an anonymous union in a class scope. An anonymous union shall not have private or protected members (Clause [class.access]). An anonymous union shall not have member functions.
A union for which objects, pointers, or references are declared is not an anonymous union. [ Example:
void f() { union { int aa; char* p; } obj, *ptr = &obj; aa = 1; // error ptr->aa = 1; // OK }
The assignment to plain aa is ill-formed since the member name is not visible outside the union, and even if it were visible, it is not associated with any particular object. — end example ] [ Note: Initialization of unions with no user-declared constructors is described in [dcl.init.aggr]. — end note ]
A union-like class is a union or a class that has an anonymous union as a direct member. A union-like class X has a set of variant members. If X is a union, a non-static data member of X that is not an anonymous union is a variant member of X. In addition, a non-static data member of an anonymous union that is a member of X is also a variant member of X. At most one variant member of a union may have a default member initializer. [ Example:
union U {
int x = 0;
union {
int k;
};
union {
int z;
int y = 1; // error: initialization for second variant member of U
};
};
— end example ]
A class can be declared within a function definition; such a class is called a local class. The name of a local class is local to its enclosing scope. The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function. Declarations in a local class shall not odr-use a variable with automatic storage duration from an enclosing scope. [ Example:
int x; void f() { static int s; int x; const int N = 5; extern int q(); struct local { int g() { return x; } // error: odr-use of automatic variable x int h() { return s; } // OK int k() { return ::x; } // OK int l() { return q(); } // OK int m() { return N; } // OK: not an odr-use int* n() { return &N; } // error: odr-use of automatic variable N }; } local* p = 0; // error: local not in scope
— end example ]
An enclosing function has no special access to members of the local class; it obeys the usual access rules. Member functions of a local class shall be defined within their class definition, if they are defined at all.