Working Draft, Standard for Programming Language C++ (N4713, 2017 year) - page 8

 

  Главная      Manuals     Working Draft, Standard for Programming Language C++ (N4713, 2017 year)

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     6      7      8      9     ..

 

 

 

Working Draft, Standard for Programming Language C++ (N4713, 2017 year) - page 8

 

 

static int s;
int j;
int :17;
int k;
} a = { 1, 2, 3 };
Here, the second initializer 2 initializes a.j and not the static data member A::s, and the third initializer 3
initializes a.k and not the unnamed bit-field before it.
— end example ]
— end note ]
10
An initializer-list is ill-formed if the number of initializer-clauses exceeds the number of elements of the
aggregate. [ Example:
char cv[4] = { ’a’, ’s’, ’d’, ’f’, 0 };
// error
is ill-formed.
— end example ]
11
If a reference member is initialized from its default member initializer and a potentially-evaluated subexpression
thereof is an aggregate initialization that would use that default member initializer, the program is ill-formed.
[ Example:
struct A;
extern A a;
struct A {
const A& a1 { A{a,a} };
// OK
const A& a2 { A{} };
// error
};
A a{a,a};
// OK
— end example ]
12
If an aggregate class C contains a subaggregate element e with no elements, the initializer-clause for e shall
not be omitted from an initializer-list for an object of type C unless the initializer-clauses for all elements of
C following e are also omitted. [ Example:
struct S { } s;
struct A {
S s1;
int i1;
S s2;
int i2;
S s3;
int i3;
} a = {
{ },
// Required initialization
0,
s,
// Required initialization
0
};
// Initialization not required for A::s3 because A::i3 is also not initialized
— end example ]
13
When initializing a multi-dimensional array, the initializer-clauses initialize the elements with the last
(rightmost) index of the array varying the fastest (11.3.4). [ Example:
int x[2][2] = { 3, 1, 4, 2 };
initializes x[0][0] to 3, x[0][1] to 1, x[1][0] to 4, and x[1][1] to 2. On the other hand,
float y[4][3] = {
{ 1 }, { 2 }, { 3 }, { 4 }
};
initializes the first column of y (regarded as a two-dimensional array) and leaves the rest zero.
— end
example ]
14
Braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the
succeeding comma-separated list of initializer-clauses initializes the elements of a subaggregate; it is erroneous
for there to be more initializer-clauses than elements. If, however, the initializer-list for a subaggregate
does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the
elements of the subaggregate; any remaining initializer-clauses are left to initialize the next element of the
aggregate of which the current subaggregate is an element. [ Example:
§ 11.6.1
202
float y[4][3] = {
{ 1, 3, 5 },
{ 2, 4, 6 },
{ 3, 5, 7 },
};
is a completely-braced initialization: 1, 3, and 5 initialize the first row of the array y[0], namely y[0][0],
y[0][1], and y[0][2]. Likewise the next two lines initialize y[1] and y[2]. The initializer ends early and
therefore y[3]s elements are initialized as if explicitly initialized with an expression of the form float(),
that is, are initialized with 0.0. In the following example, braces in the initializer-list are elided; however the
initializer-list has the same effect as the completely-braced initializer-list of the above example,
float y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};
The initializer for y begins with a left brace, but the one for y[0] does not, therefore three elements from the
list are used. Likewise the next three are taken successively for y[1] and y[2].
— end example ]
15
All implicit type conversions (Clause 7) are considered when initializing the element with an assignment-
expression. If the assignment-expression can initialize an element, the element is initialized. Otherwise, if the
element is itself a subaggregate, brace elision is assumed and the assignment-expression is considered for the
initialization of the first element of the subaggregate. [ Note: As specified above, brace elision cannot apply
to subaggregates with no elements; an initializer-clause for the entire subobject is required. — end note ]
[ Example:
struct A {
int i;
operator int();
};
struct B {
A a1, a2;
int z;
};
A a;
B b = { 4, a, a };
Braces are elided around the initializer-clause for b.a1.i. b.a1.i is initialized with 4, b.a2 is initialized
with a, b.z is initialized with whatever a.operator int() returns.
— end example ]
16
[ Note: An aggregate array or an aggregate class may contain elements of a class type with a user-provided
constructor (15.1). Initialization of these aggregate objects is described in 15.6.1.
— end note ]
17
[ Note: Whether the initialization of aggregates with static storage duration is static or dynamic is specified
in 6.8.3.2, 6.8.3.3, and 9.7.
— end note ]
18
When a union is initialized with an initializer list, there shall not be more than one explicitly initialized
element. [ Example:
union u { int a; const char* b; };
u a = { 1 };
u b = a;
u c = 1;
// error
u d = { 0, "asdf" };
// error
u e = { "asdf" };
// error
u f = { .b = "asdf" };
u g = { .a = 1, .b = "asdf" };
// error
— end example ]
19
[ Note: As described above, the braces around the initializer-clause for a union member can be omitted if the
union is a member of another aggregate.
— end note ]
11.6.2
Character arrays
[dcl.init.string]
1
An array of narrow character type (6.7.1), char16_t array, char32_t array, or wchar_t array can be initialized
by a narrow string literal, char16_t string literal, char32_t string literal, or wide string literal, respectively,
or by an appropriately-typed string literal enclosed in braces (5.13.5). Successive characters of the value of
the string literal initialize the elements of the array. [ Example:
§ 11.6.2
203
char msg[] = "Syntax error on line %s\n";
shows a character array whose members are initialized with a string-literal. Note that because ’\n’ is a
single character and because a trailing ’\0’ is appended, sizeof(msg) is 25.
— end example ]
2
There shall not be more initializers than there are array elements. [ Example:
char cv[4] = "asdf";
// error
is ill-formed since there is no space for the implied trailing ’\0’.
— end example ]
3
If there are fewer initializers than there are array elements, each element not explicitly initialized shall be
zero-initialized (11.6).
11.6.3
References
[dcl.init.ref]
1
A variable whose declared type is “reference to type T” (11.3.2) shall be initialized. [ Example:
int g(int) noexcept;
void f() {
int i;
int& r = i;
// r refers to i
r = 1;
// the value of i becomes 1
int* p = &r;
// p points to i
int& rr = r;
// rr refers to what r refers to, that is, to i
int (&rg)(int) = g;
// rg refers to the function g
rg(i);
// calls function g
int a[3];
int (&ra)[3] = a;
// ra refers to the array a
ra[1] = i;
// modifies a[1]
}
— end example ]
2
A reference cannot be changed to refer to another object after initialization. [ Note: Assignment to a reference
assigns to the object referred to by the reference (8.5.18).
— end note ] Argument passing (8.5.1.2) and
function value return (9.6.3) are initializations.
3
The initializer can be omitted for a reference only in a parameter declaration (11.3.5), in the declaration of a
function return type, in the declaration of a class member within its class definition (12.2), and where the
extern specifier is explicitly used. [ Example:
int& r1;
// error: initializer missing
extern int& r2;
// OK
— end example ]
4
Given types “cv1 T1” and “cv2 T2”, “cv1 T1” is reference-related to “cv2 T2” if T1 is the same type as T2,
or T1 is a base class of T2. “cv1 T1” is reference-compatible with “cv2 T2” if
(4.1)
T1 is reference-related to T2, or
(4.2)
T2 is “noexcept function” and T1 is “function”, where the function types are otherwise the same,
and cv1 is the same cv-qualification as, or greater cv-qualification than, cv2. In all cases where the reference-
related or reference-compatible relationship of two types is used to establish the validity of a reference
binding, and T1 is a base class of T2, a program that necessitates such a binding is ill-formed if T1 is an
inaccessible (Clause 14) or ambiguous (13.2) base class of T2.
5
A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:
(5.1)
If the reference is an lvalue reference and the initializer expression
(5.1.1)
is an lvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2”, or
(5.1.2)
has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be
converted to an lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3108
(this conversion is selected by enumerating the applicable conversion functions (16.3.1.6) and
choosing the best one through overload resolution (16.3)),
then the reference is bound to the initializer expression lvalue in the first case and to the lvalue result
of the conversion in the second case (or, in either case, to the appropriate base class subobject of the
108) This requires a conversion function (15.3.2) returning a reference type.
§ 11.6.3
204
object). [Note: The usual lvalue-to-rvalue (7.1), array-to-pointer (7.2), and function-to-pointer (7.3)
standard conversions are not needed, and therefore are suppressed, when such direct bindings to lvalues
are done.
— end note ]
[ Example:
double d = 2.0;
double& rd = d;
// rd refers to d
const double& rcd = d;
// rcd refers to d
struct A { };
struct B : A { operator int&(); } b;
A& ra = b;
// ra refers to A subobject in b
const A& rca = b;
// rca refers to A subobject in b
int& ir = B();
// ir refers to the result of B::operator int&
— end example ]
(5.2)
Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be
const), or the reference shall be an rvalue reference. [ Example:
double& rd2 = 2.0;
// error: not an lvalue and reference not const
int i = 2;
double& rd3 = i;
// error: type mismatch and reference not const
— end example ]
(5.2.1)
If the initializer expression
(5.2.1.1)
is an rvalue (but not a bit-field) or function lvalue and “cv1 T1” is reference-compatible with
“cv2 T2”, or
(5.2.1.2)
has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can
be converted to an rvalue or function lvalue of type “cv3 T3”, where “cv1 T1” is reference-
compatible with “cv3 T3” (see 16.3.1.6),
then the value of the initializer expression in the first case and the result of the conversion in
the second case is called the converted initializer. If the converted initializer is a prvalue, its
type T4 is adjusted to type “cv1 T4” (7.5) and the temporary materialization conversion (7.4) is
applied. In any case, the reference is bound to the resulting glvalue (or to an appropriate base
class subobject).
[ Example:
struct A { };
struct B : A { } b;
extern B f();
const A& rca2 = f();
// bound to the A subobject of the B rvalue.
A&& rra = f();
// same as above
struct X {
operator B();
operator int&();
} x;
const A& r = x;
// bound to the A subobject of the result of the conversion
int i2 = 42;
int&& rri = static_cast<int&&>(i2); // bound directly to i2
B&& rrb = x;
// bound directly to the result of operator B
— end example ]
(5.2.2)
Otherwise:
(5.2.2.1)
If T1 or T2 is a class type and T1 is not reference-related to T2, user-defined conversions
are considered using the rules for copy-initialization of an object of type “cv1 T1” by user-
defined conversion (11.6, 16.3.1.4, 16.3.1.5); the program is ill-formed if the corresponding
non-reference copy-initialization would be ill-formed. The result of the call to the conversion
function, as described for the non-reference copy-initialization, is then used to direct-initialize
the reference. For this direct-initialization, user-defined conversions are not considered.
(5.2.2.2)
Otherwise, the initializer expression is implicitly converted to a prvalue of type “cv1 T1”. The
temporary materialization conversion is applied and the reference is bound to the result.
§ 11.6.3
205
If T1 is reference-related to T2:
(5.2.2.3)
cv1 shall be the same cv-qualification as, or greater cv-qualification than, cv2 ; and
(5.2.2.4)
if the reference is an rvalue reference, the initializer expression shall not be an lvalue.
[ Example:
struct Banana { };
struct Enigma { operator const Banana(); };
struct Alaska { operator Banana&(); };
void enigmatic() {
typedef const Banana ConstBanana;
Banana &&banana1 = ConstBanana(); // ill-formed
Banana &&banana2 = Enigma();
// ill-formed
Banana &&banana3 = Alaska();
// ill-formed
}
const double& rcd2 = 2;
// rcd2 refers to temporary with value 2.0
double&& rrd = 2;
// rrd refers to temporary with value 2.0
const volatile int cvi = 1;
const int& r2 = cvi;
// error: cv-qualifier dropped
struct A { operator volatile int&(); } a;
const int& r3 = a;
// error: cv-qualifier dropped
// from result of conversion function
double d2 = 1.0;
double&& rrd2 = d2;
// error: initializer is lvalue of related type
struct X { operator int&(); };
int&& rri2 = X();
// error: result of conversion function is lvalue of related type
int i3 = 2;
double&& rrd3 = i3;
// rrd3 refers to temporary with value 2.0
— end example ]
In all cases except the last (i.e., implicitly converting the initializer expression to the underlying type of the
reference), the reference is said to bind directly to the initializer expression.
6
[ Note: 15.2 describes the lifetime of temporaries bound to references.
— end note ]
11.6.4
List-initialization
[dcl.init.list]
1
List-initialization is initialization of an object or reference from a braced-init-list. Such an initializer is called
an initializer list, and the comma-separated initializer-clauses of the initializer-list or designated-initializer-
clauses of the designated-initializer-list are called the elements of the initializer list. An initializer list may be
empty. List-initialization can occur in direct-initialization or copy-initialization contexts; list-initialization in
a direct-initialization context is called direct-list-initialization and list-initialization in a copy-initialization
context is called copy-list-initialization. [ Note: List-initialization can be used
(1.1)
as the initializer in a variable definition (11.6)
(1.2)
as the initializer in a new-expression (8.5.2.4)
(1.3)
in a return statement (9.6.3)
(1.4)
as a for-range-initializer (9.5)
(1.5)
as a function argument (8.5.1.2)
(1.6)
as a subscript (8.5.1.1)
(1.7)
as an argument to a constructor invocation (11.6, 8.5.1.3)
(1.8)
as an initializer for a non-static data member (12.2)
(1.9)
in a mem-initializer (15.6.2)
(1.10)
on the right-hand side of an assignment (8.5.18)
[ Example:
int a = {1};
std::complex<double> z{1,2};
new std::vector<std::string>{"once", "upon", "a", "time"};
// 4 string elements
f( {"Nicholas","Annemarie"} );
// pass list of two elements
§ 11.6.4
206
return { "Norah" };
// return list of one element
int* e {};
// initialization to zero / null pointer
x = double{1};
// explicitly construct a double
std::map<std::string,int> anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} };
— end example ]
— end note ]
2
A constructor is an initializer-list constructor if its first parameter is of type std::initializer_list<E> or
reference to possibly cv-qualified std::initializer_list<E> for some type E, and either there are no other
parameters or else all other parameters have default arguments (11.3.6). [ Note: Initializer-list constructors
are favored over other constructors in list-initialization (16.3.1.7). Passing an initializer list as the argument to
the constructor template template<class T> C(T) of a class C does not create an initializer-list constructor,
because an initializer list argument causes the corresponding parameter to be a non-deduced context (17.9.2.1).
— end note ] The template std::initializer_list is not predefined; if the header <initializer_list>
is not included prior to a use of std::initializer_list — even an implicit use in which the type is not
named (10.1.7.4) — the program is ill-formed.
3
List-initialization of an object or reference of type T is defined as follows:
(3.1)
If the braced-init-list contains a designated-initializer-list, T shall be an aggregate class. The ordered
identifiers in the designators of the designated-initializer-list shall form a subsequence of the ordered
identifiers in the direct non-static data members of T. Aggregate initialization is performed (11.6.1).
[ Example:
struct A { int x; int y; int z; };
A a{.y = 2, .x = 1};
// error: designator order does not match declaration order
A b{.x = 1, .z = 2};
// OK, b.y initialized to 0
— end example ]
(3.2)
If T is an aggregate class and the initializer list has a single element of type cv U, where U is T or a
class derived from T, the object is initialized from that element (by copy-initialization for copy-list-
initialization, or by direct-initialization for direct-list-initialization).
(3.3)
Otherwise, if T is a character array and the initializer list has a single element that is an appropriately-
typed string literal (11.6.2), initialization is performed as described in that subclause.
(3.4)
Otherwise, if T is an aggregate, aggregate initialization is performed (11.6.1).
[ Example:
double ad[] = { 1, 2.0 };
// OK
int ai[] = { 1, 2.0 };
// error: narrowing
struct S2 {
int m1;
double m2, m3;
};
S2 s21 = { 1, 2, 3.0 };
// OK
S2 s22 { 1.0, 2, 3 };
// error: narrowing
S2 s23 { };
// OK: default to 0,0,0
— end example ]
(3.5)
Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the
object is value-initialized.
(3.6)
Otherwise, if T is a specialization of std::initializer_list<E>, the object is constructed as described
below.
(3.7)
Otherwise, if T is a class type, constructors are considered. The applicable constructors are enumerated
and the best one is chosen through overload resolution (16.3, 16.3.1.7). If a narrowing conversion (see
below) is required to convert any of the arguments, the program is ill-formed.
[ Example:
struct S {
S(std::initializer_list<double>); // #1
S(std::initializer_list<int>);
// #2
S();
// #3
§ 11.6.4
207
// ...
};
S s1 = { 1.0, 2.0, 3.0 };
// invoke #1
S s2 = { 1, 2, 3 };
// invoke #2
S s3 = { };
// invoke #3
— end example ]
[ Example:
struct Map {
Map(std::initializer_list<std::pair<std::string,int>>);
};
Map ship = {{"Sophie",14}, {"Surprise",28}};
— end example ]
[ Example:
struct S {
// no initializer-list constructors
S(int, double, double);
// #1
S();
// #2
// ...
};
S s1 = { 1, 2, 3.0 };
// OK: invoke #1
S s2 { 1.0, 2, 3 };
// error: narrowing
S s3 { };
// OK: invoke #2
— end example ]
(3.8)
Otherwise, if T is an enumeration with a fixed underlying type (10.2), the initializer-list has a single
element v, and the initialization is direct-list-initialization, the object is initialized with the value
T(v) (8.5.1.3); if a narrowing conversion is required to convert v to the underlying type of T, the
program is ill-formed. [ Example:
enum byte : unsigned char { };
byte b { 42 };
// OK
byte c = { 42 };
// error
byte d = byte{ 42 };
// OK; same value as b
byte e { -1 };
// error
struct A { byte b; };
A a1 = { { 42 } };
// error
A a2 = { byte{ 42 } };
// OK
void f(byte);
f({ 42 });
// error
enum class Handle : uint32_t { Invalid = 0 };
Handle h { 42 };
// OK
— end example ]
(3.9)
Otherwise, if the initializer list has a single element of type E and either T is not a reference type or its
referenced type is reference-related to E, the object or reference is initialized from that element (by
copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization); if a
narrowing conversion (see below) is required to convert the element to T, the program is ill-formed.
[ Example:
int x1 {2};
// OK
int x2 {2.0};
// error: narrowing
— end example ]
(3.10)
Otherwise, if T is a reference type, a prvalue of the type referenced by T is generated. The prvalue
initializes its result object by copy-list-initialization or direct-list-initialization, depending on the kind
of initialization for the reference. The prvalue is then used to direct-initialize the reference. [ Note: As
usual, the binding will fail and the program is ill-formed if the reference type is an lvalue reference to a
non-const type.
— end note ]
§
11.6.4
208
[ Example:
struct S {
S(std::initializer_list<double>); // #1
S(const std::string&);
// #2
// ...
};
const S& r1 = { 1, 2, 3.0 };
// OK: invoke #1
const S& r2 { "Spinach" };
// OK: invoke #2
S& r3 = { 1, 2, 3 };
// error: initializer is not an lvalue
const int& i1 = { 1 };
// OK
const int& i2 = { 1.1 };
// error: narrowing
const int (&iar)[2] = { 1, 2 };
// OK: iar is bound to temporary array
— end example ]
(3.11)
Otherwise, if the initializer list has no elements, the object is value-initialized.
[ Example:
int** pp {};
// initialized to null pointer
— end example ]
(3.12)
Otherwise, the program is ill-formed.
[ Example:
struct A { int i; int j; };
A a1 { 1, 2 };
// aggregate initialization
A a2 { 1.2 };
// error: narrowing
struct B {
B(std::initializer_list<int>);
};
B b1 { 1, 2 };
// creates initializer_list<int> and calls constructor
B b2 { 1, 2.0 };
// error: narrowing
struct C {
C(int i, double j);
};
C c1 = { 1, 2.2 };
// calls constructor with arguments (1, 2.2)
C c2 = { 1.1, 2 };
// error: narrowing
int j { 1 };
// initialize to 1
int k { };
// initialize to 0
— end example ]
4
Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack
expansions (17.6.3), are evaluated in the order in which they appear. That is, every value computation and
side effect associated with a given initializer-clause is sequenced before every value computation and side
effect associated with any initializer-clause that follows it in the comma-separated list of the initializer-list.
[ Note: This evaluation ordering holds regardless of the semantics of the initialization; for example, it applies
when the elements of the initializer-list are interpreted as arguments of a constructor call, even though
ordinarily there are no sequencing constraints on the arguments of a call.
— end note ]
5
An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation
generated and materialized (7.4) a prvalue of type “array of N const E”, where N is the number of elements
in the initializer list. Each element of that array is copy-initialized with the corresponding element of the
initializer list, and the std::initializer_list<E> object is constructed to refer to that array. [ Note: A
constructor or conversion function selected for the copy shall be accessible (Clause 14) in the context of
the initializer list.
— end note ] If a narrowing conversion is required to initialize any of the elements, the
program is ill-formed. [ Example:
struct X {
X(std::initializer_list<double> v);
};
X x{ 1,2,3 };
The initialization will be implemented in a way roughly equivalent to this:
const double __a[3] = {double{1}, double{2}, double{3}};
§ 11.6.4
209
X x(std::initializer_list<double>(__a, __a+3));
assuming that the implementation can construct an initializer_list object with a pair of pointers.
— end
example ]
6
The array has the same lifetime as any other temporary object (15.2), except that initializing an initializer_-
list object from the array extends the lifetime of the array exactly like binding a reference to a temporary.
[ Example:
typedef std::complex<double> cmplx;
std::vector<cmplx> v1 = { 1, 2, 3 };
void f() {
std::vector<cmplx> v2{ 1, 2, 3 };
std::initializer_list<int> i3 = { 1, 2, 3 };
}
struct A {
std::initializer_list<int> i4;
A() : i4{ 1, 2, 3 } {}
// ill-formed, would create a dangling reference
};
For v1 and v2, the initializer_list object is a parameter in a function call, so the array created for { 1,
2, 3 } has full-expression lifetime. For i3, the initializer_list object is a variable, so the array persists
for the lifetime of the variable. For i4, the initializer_list object is initialized in the constructor’s
ctor-initializer as if by binding a temporary array to a reference member, so the program is ill-formed (15.6.2).
— end example ] [ Note: The implementation is free to allocate the array in read-only memory if an explicit
array with the same initializer could be so allocated.
— end note ]
7
A narrowing conversion is an implicit conversion
(7.1)
from a floating-point type to an integer type, or
(7.2)
from long double to double or float, or from double to float, except where the source is a constant
expression and the actual value after conversion is within the range of values that can be represented
(even if it cannot be represented exactly), or
(7.3)
from an integer type or unscoped enumeration type to a floating-point type, except where the source is
a constant expression and the actual value after conversion will fit into the target type and will produce
the original value when converted back to the original type, or
(7.4)
from an integer type or unscoped enumeration type to an integer type that cannot represent all the
values of the original type, except where the source is a constant expression whose value after integral
promotions will fit into the target type.
[Note: As indicated above, such conversions are not allowed at the top level in list-initializations. — end
note ]
[ Example:
int x = 999;
// x is not a constant expression
const int y = 999;
const int z = 99;
char c1 = x;
// OK, though it might narrow (in this case, it does narrow)
char c2{x};
// error: might narrow
char c3{y};
// error: narrows (assuming char is 8 bits)
char c4{z};
// OK: no narrowing needed
unsigned char uc1 = {5};
// OK: no narrowing needed
unsigned char uc2 = {-1};
// error: narrows
unsigned int ui1 = {-1};
// error: narrows
signed int si1 =
{ (unsigned int)-1 };
// error: narrows
int ii = {2.0};
// error: narrows
float f1 { x };
// error: might narrow
float f2 { 7 };
// OK: 7 can be exactly represented as a float
int f(int);
int a[] = { 2, f(2), f(2.0) };
// OK: the double-to-int conversion is not at the top level
— end example ]
§ 11.6.4
210
12
Classes
[class]
1
A class is a type. Its name becomes a class-name (12.1) within its scope.
class-name:
identifier
simple-template-id
Class-specifier s and elaborated-type-specifier s (10.1.7.3) 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 ]
2
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.
3
If a class is marked with the class-virt-specifier final and it appears as a class-or-decltype in a base-
clause (Clause 13), 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 ]
4
Complete objects and member subobjects of class type shall have nonzero size.109 [ 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 15.8). Other plausible operators, such as equality comparison, can
be defined by the user; see 16.5.
— end note ]
5
A union is a class defined with the class-key union; it holds at most one data member at a time (12.3).
[ Note: Aggregates of class type are described in 11.6.1.
— end note ]
6
A trivially copyable class is a class:
109) Base class subobjects are not so constrained.
Classes
211
(6.1)
where each copy constructor, move constructor, copy assignment operator, and move assignment
operator (15.8, 16.5.3) is either deleted or trivial,
(6.2)
that has at least one non-deleted copy constructor, move constructor, copy assignment operator, or
move assignment operator, and
(6.3)
that has a trivial, non-deleted destructor (15.4).
A trivial class is a class that is trivially copyable and has one or more default constructors (15.1), 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 ]
7
A class S is a standard-layout class if it:
(7.1)
has no non-static data members of type non-standard-layout class (or array of such types) or reference,
(7.2)
has no virtual functions (13.3) and no virtual base classes (13.1),
(7.3)
has the same access control (Clause 14) for all non-static data members,
(7.4)
has no non-standard-layout base classes,
(7.5)
has at most one base class subobject of any given type,
(7.6)
has all non-static data members and bit-fields in the class and its base classes first declared in the same
class, and
(7.7)
has no element of the set M (S) of types (defined below) as a base class.110
M (X) is defined as follows:
(7.8)
If X is a non-union class type with no (possibly inherited (Clause 13)) non-static data members, the set
M (X) is empty.
(7.9)
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).
(7.10)
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.
(7.11)
If X is an array type with element type Xe, the set M (X) consists of Xe and the elements of M (Xe).
(7.12)
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 ]
8
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.
9
[Note: Standard-layout classes are useful for communicating with code written in other programming
languages. Their layout is specified in 12.2. — end note ]
10
[ Example:
struct N {
// neither trivial nor standard-layout
int i;
int j;
110) 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 (8.5.10).
Classes
212
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 ]
11
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 (10.3.1) 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.
12.1
Class names
[class.name]
1
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 (Clause 16) 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 ]
2
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 (6.3). 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 (6.4.4). [ Example:
struct stat {
// ...
};
stat gstat;
// use plain stat to define variable
int stat(struct stat*);
// redeclare stat as function
§ 12.1
213
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 14.3, operator functions in 16.5.
— end example ]
— end note ]
3
[ Note: An elaborated-type-specifier (10.1.7.3) 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 ]
4
[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 ]
5
A typedef-name (10.1.3) 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.
12.2
Class members
[class.mem]
member-specification:
member-declaration member-specificationopt
access-specifier : member-specificationopt
§ 12.2
214
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 requires-clause
declarator brace-or-equal-initializeropt
identifieropt attribute-specifier-seqopt : constant-expression brace-or-equal-initializeropt
virt-specifier-seq:
virt-specifier
virt-specifier-seq virt-specifier
virt-specifier:
override
final
pure-specifier:
= 0
1
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 (12.3.1) and direct members thereof.
Members of a class are data members, member functions (12.2.1), nested types, enumerators, and member
templates (17.6.2) 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 ]
2
A member-declaration does not declare new members of the class if it is
(2.1)
a friend declaration (14.3),
(2.2)
a static_assert-declaration,
(2.3)
a using-declaration (10.3.3), or
(2.4)
an empty-declaration.
For any other member-declaration, each declared entity that is not an unnamed bit-field (12.2.4) 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.
3
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 (12.1, 12.2.5) and enumerations (10.2) declared in the
class and arbitrary types declared as members by use of a typedef declaration (10.1.3) or alias-declaration.
The enumerators of an unscoped enumeration (10.2) defined in the class are members of the class.
4
A data member or member function may be declared static in its member-declaration, in which case it is a
static member (see 12.2.3) (a static data member (12.2.3.2) or static member function (12.2.3.1), 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 (12.2.2), respectively). [Note: A non-static data member of non-reference
type is a member subobject of a class object (6.6.2). — end note ]
5
A member shall not be declared twice in the member-specification, except that
(5.1)
a nested class or member class template can be declared and then later defined, and
(5.2)
an enumeration can be introduced with an opaque-enum-declaration and later redeclared with an
enum-specifier .
§ 12.2
215
[ Note: A single name can denote several member functions provided their types are sufficiently different (Clause
16).
— end note ]
6
A class is considered a completely-defined object type (6.7) (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.
7
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 ]
8
In a member-declarator for a bit-field, the constant-expression is parsed as the longest sequence of tokens
that could syntactically form a constant-expression. [ Example:
int a;
const int b = 0;
struct S {
int x1 : 8 = 42;
// OK, "= 42" is brace-or-equal-initializer
int x2 : 8 { 42 };
// OK, "{ 42 }" is brace-or-equal-initializer
int y1 : true ? 8 : a = 42;
// OK, brace-or-equal-initializer is absent
int y2 : true ? 8 : b = 42;
// error: cannot assign to const int
int y3 : (true ? 8 : b) = 42;
// OK, "= 42" is brace-or-equal-initializer
int z : 1 || new int { 0 };
// OK, brace-or-equal-initializer is absent
};
— end example ]
9
A brace-or-equal-initializer shall appear only in the declaration of a data member. (For static data members,
see 12.2.3.2; for non-static data members, see 15.6.2 and 11.6.1). 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.
10
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.
11
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 (14.3). A pure-specifier shall be used only in the declaration of a virtual function (13.3)
that is not a friend declaration.
12
The optional attribute-specifier-seq in a member-declaration appertains to each of the entities declared by the
member-declarator s; it shall not appear if the optional member-declarator-list is omitted.
13
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 (13.3).
14
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.
15
[Note: See 8.4 for restrictions on the use of non-static data members and non-static member functions.
— end note ]
16
[ 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 ]
17
[ Example: A simple example of a class definition is
struct tnode {
char tword[20];
§ 12.2
216
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 ]
18
Non-static data members of a (non-union) class with the same access control (Clause 14) 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 (Clause 14). 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 (13.3) and virtual base classes (13.1).
19
If T is the name of a class, then each of the following shall have a name different from T:
(19.1)
every static data member of class T;
(19.2)
every member function of class T [ Note: This restriction does not apply to constructors, which do not
have names (15.1) — end note ] ;
(19.3)
every member of class T that is itself a type;
(19.4)
every member template of class T;
(19.5)
every enumerator of every member of class T that is an unscoped enumerated type; and
(19.6)
every member of every anonymous union that is a member of class T.
20
In addition, if class T has a user-declared constructor (15.1), every non-static data member of class T shall
have a name different from T.
21
The common initial sequence of two standard-layout struct (Clause 12) 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 ]
22
Two standard-layout struct (Clause 12) types are layout-compatible classes if their common initial sequence
comprises all members and bit-fields of both classes (6.7).
23
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 (6.7).
24
In a standard-layout union with an active member (12.3) 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
}
§ 12.2
217
— end example ]
[Note: Reading a volatile object through a non-volatile glvalue has undefined behavior
(10.1.7.1).
— end note ]
25
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 (6.7.2, 8.5.1.9).
— end note ]
12.2.1
Member functions
[class.mfct]
1
A member function may be defined (11.4) in its class definition, in which case it is an inline member
function (10.1.6), 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 (17.8) appearing outside of the class definition, a member function
shall not be redeclared.
2
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 (12.4) have no linkage. See 6.5.
— end note ]
3
[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 6.2 and 10.1.6.
— end note ]
4
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 (11.3.6) or in the
member function body) is looked up as described in 6.4.
— 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 ]
5
[ 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 ]
6
Previously declared member functions may be mentioned in friend declarations.
7
Member functions of a local class shall be defined inline in their class definition, if they are defined at all.
8
[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 11.3.5. 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 17.3.
— end note ]
§ 12.2.1
218
12.2.2
Non-static member functions
[class.mfct.non-static]
1
A non-static member function may be called for an object of its class type, or for an object of a class
derived (Clause 13) from its class type, using the class member access syntax (8.5.1.5, 16.3.1.1). A non-static
member function may also be called directly using the function call syntax (8.5.1.2, 16.3.1.1) from within the
body of a member function of its class or of a class derived from its class.
2
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.
3
When an id-expression (8.4) that is not part of a class member access syntax (8.5.1.5) and not used to form
a pointer to member (8.5.2.1) is used in a member of class X in a context where this can be used (8.4.2), if
name lookup (6.4) 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 (8.5.1.5) using (*this) (12.2.2.1) 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 (8.4) 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 (8.4) in which the nested-name-specifier
names the class of the member function. These transformations do not apply in the template definition
context (17.7.2.1). [ 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.111
— end example ]
4
A non-static member function may be declared const, volatile, or const volatile. These cv-qualifiers
affect the type of the this pointer (12.2.2.1). They also affect the function type (11.3.5) 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 ]
5
A non-static member function may be declared with a ref-qualifier (11.3.5); see 16.3.1.
6
A non-static member function may be declared virtual (13.3) or pure virtual (13.4).
111) See, for example, <cstring> (24.5).
§ 12.2.2
219
12.2.2.1
The this pointer
[class.this]
1
In the body of a non-static (12.2.1) 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 ]
2
Similarly, volatile semantics (10.1.7.1) apply in volatile member functions when accessing the object and
its non-static data members.
3
A cv-qualified member function can be called on an object-expression (8.5.1.5) 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 ]
4
Constructors (15.1) and destructors (15.4) 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 15.1
and 15.4.
— end note ]
12.2.3
Static members
[class.static]
1
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 (8.5.1.5) 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 ]
2
A static member may be referred to directly in the scope of its class or in the scope of a class derived (Clause
13) 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();
};
§ 12.2.3
220
struct Y : X {
static int i;
};
int Y::i = g();
// equivalent to Y::g();
— end example ]
3
If an unqualified-id (8.4) is used in the definition of a static member following the member’s declarator-id,
and name lookup (6.4.1) 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 8.4 for restrictions on the use of non-static data members and non-static member
functions.
— end note ]
4
Static members obey the usual class member access rules (Clause 14). 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 ]
12.2.3.1
Static member functions
[class.static.mfct]
1
[ Note: The rules described in 12.2.1 apply to static member functions.
— end note ]
2
[Note: A static member function does not have a this pointer (12.2.2.1).
— 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 (16.1). A static member function shall not be declared const, volatile,
or const volatile.
12.2.3.2
Static data members
[class.static.data]
1
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.
2
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 (6.3.7). [ 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 ]
3
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 (8.6). The member shall still be defined in a namespace scope
if it is odr-used (6.2) 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 D.1). Declarations of other static data members shall not specify a
brace-or-equal-initializer.
§ 12.2.3.2
221
4
[ Note: There shall be exactly one definition of a static data member that is odr-used (6.2) 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.
5
[ Note: Static data members of a class in namespace scope have the linkage of that class (6.5). A local class
cannot have static data members (12.4).
— end note ]
6
Static data members are initialized and destroyed exactly like non-local variables (6.8.3.2, 6.8.3.3, 6.8.3.4).
7
A static data member shall not be mutable (10.1.1).
12.2.4
Bit-fields
[class.bit]
1
A member-declarator of the form
identifieropt attribute-specifier-seqopt : constant-expression brace-or-equal-initializeropt
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 (6.7) of the bit-field’s type; in such cases the extra bits are padding bits (6.7). 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 ]
2
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.
3
A bit-field shall not be a static member. A bit-field shall have integral or enumeration type (6.7.1). 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 (11.6.3). [ 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 11.6.3.
— end note ]
4
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 (10.2), 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 ]
12.2.5
Nested class declarations
[class.nest]
1
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 8.4 for restrictions on the use of non-static data members and non-static member functions.
— end note ]
[ Example:
int x;
§ 12.2.5
222
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 ]
2
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 ]
3
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 ]
4
Like a member function, a friend function (14.3) 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 (12.2.3), but it has
no special access rights to members of an enclosing class.
12.2.6
Nested type names
[class.nested.type]
1
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
§ 12.2.6
223
X::Y d;
// OK
X::I e;
// OK
— end example ]
12.3
Unions
[class.union]
1
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 (6.6.3). 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 (12.2), 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 12.2.
— end note ]
2
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 (6.7.2, 8.5.1.9). As a consequence, all non-static data members of a
union object have the same address.
— end note ]
3
A union can have member functions (including constructors and destructors), but it shall not have virtual (13.3)
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 (12.2), if any non-static data member of a union has a non-trivial default constructor (15.1), copy
constructor (15.8), move constructor (15.8), copy assignment operator (15.8), move assignment operator (15.8),
or destructor (15.4), the corresponding member function of the union must be user-provided or it will be
implicitly deleted (11.4.3) for the union.
— end note ]
4
[ Example: Consider the following union:
union U {
int i;
float f;
std::string s;
};
Since std::string (24.3) 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 ]
5
When the left operand of an assignment operator involves a member access expression (8.5.1.5) 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:
(5.1)
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.
(5.2)
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.
(5.3)
Otherwise, S(E) is empty.
In an assignment expression of the form E1 = E2 that uses either the built-in assignment operator (8.5.18) or
a trivial assignment operator (15.8), for each element X of S(E1), if modification of X would have undefined
behavior under 6.6.3, 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 (6.6.3).
— 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;
§ 12.3
224
// 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 6.6.3)
}
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 (12.2)
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 ]
6
[ 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 ]
12.3.1
Anonymous unions
[class.union.anon]
1
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 ]
2
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 14). An anonymous
union shall not have member functions.
3
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 11.6.1.
— end note ]
§ 12.3.1
225
4
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 ]
12.4
Local class declarations
[class.local]
1
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. [ Note: A declaration in a local class
cannot odr-use (6.2) a local entity from an enclosing scope.
— end note ] [ Example:
int x;
void f() {
static int s;
int x;
const int N = 5;
extern int q();
int arr[2];
auto [y, z] = arr;
struct local {
int g() { return x; }
// error: odr-use of non-odr-usable 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 non-odr-usable variable N
int p() { return y; }
// error: odr-use of non-odr-usable structured binding y
};
}
local* p = 0;
// error: local not in scope
— end example ]
2
An enclosing function has no special access to members of the local class; it obeys the usual access rules (Clause
14). Member functions of a local class shall be defined within their class definition, if they are defined at all.
3
If class X is a local class a nested class Y may be declared in class X and later defined in the definition of class
X or be later defined in the same scope as the definition of class X. A class nested within a local class is a
local class.
4
A local class shall not have static data members.
§ 12.4
226
13
Derived classes
[class.derived]
1
A list of base classes can be specified in a class definition using the notation:
base-clause:
: base-specifier-list
base-specifier-list:
base-specifier ...opt
base-specifier-list , base-specifier ...opt
base-specifier:
attribute-specifier-seqopt class-or-decltype
attribute-specifier-seqopt virtual access-specifieropt class-or-decltype
attribute-specifier-seqopt access-specifier virtualopt class-or-decltype
class-or-decltype:
nested-name-specifieropt class-name
nested-name-specifier template simple-template-id
decltype-specifier
access-specifier:
private
protected
public
The optional attribute-specifier-seq appertains to the base-specifier.
2
A class-or-decltype shall denote a class type that is not an incompletely defined class (Clause 12). The class
denoted by the class-or-decltype of a base-specifier is called a direct base class for the class being defined.
During the lookup for a base class name, non-type names are ignored (6.3.10). If the name found is not a
class-name, the program is ill-formed. A class B is a base class of a class D if it is a direct base class of D or a
direct base class of one of D’s base classes. A class is an indirect base class of another if it is a base class
but not a direct base class. A class is said to be (directly or indirectly) derived from its (direct or indirect)
base classes. [ Note: See Clause 14 for the meaning of access-specifier.
— end note ] Unless redeclared in the
derived class, members of a base class are also considered to be members of the derived class. Members of a
base class other than constructors are said to be inherited by the derived class. Constructors of a base class
can also be inherited as described in 10.3.3. Inherited members can be referred to in expressions in the same
manner as other members of the derived class, unless their names are hidden or ambiguous (13.2). [Note:
The scope resolution operator :: (8.4) can be used to refer to a direct or indirect base member explicitly.
This allows access to a name that has been redeclared in the derived class. A derived class can itself serve as
a base class subject to access control; see 14.2. A pointer to a derived class can be implicitly converted to a
pointer to an accessible unambiguous base class (7.11). An lvalue of a derived class type can be bound to a
reference to an accessible unambiguous base class (11.6.3).
— end note ]
3
The base-specifier-list specifies the type of the base class subobjects contained in an object of the derived
class type. [ Example:
struct Base {
int a, b, c;
};
struct Derived : Base {
int b;
};
struct Derived2 : Derived {
int c;
};
Here, an object of class Derived2 will have a subobject of class Derived which in turn will have a subobject
of class Base.
— end example ]
4
A base-specifier followed by an ellipsis is a pack expansion (17.6.3).
Derived classes
227
5
The order in which the base class subobjects are allocated in the most derived object (6.6.2) is unspecified.
[Note: A derived class and its base class subobjects can be represented by a directed acyclic graph (DAG)
where an arrow means “directly derived from”. An arrow need not have a physical representation in memory.
A DAG of subobjects is often referred to as a “subobject lattice”.
Base
Derived1
Derived2
Figure 2 — Directed acyclic graph
— end note ]
6
[ Note: Initialization of objects representing base classes can be specified in constructors; see 15.6.2.
— end
note ]
7
[ Note: A base class subobject might have a layout (6.6.4) different from the layout of a most derived object
of the same type. A base class subobject might have a polymorphic behavior (15.7) different from the
polymorphic behavior of a most derived object of the same type. A base class subobject may be of zero
size (Clause 12); however, two subobjects that have the same class type and that belong to the same most
derived object must not be allocated at the same address (8.5.10).
— end note ]
13.1
Multiple base classes
[class.mi]
1
A class can be derived from any number of base classes. [ Note: The use of more than one direct base class is
often called multiple inheritance.
— end note ] [ Example:
class A { /* ... */ };
class B { /* ... */ };
class C { /* ... */ };
class D : public A, public B, public C { /* ... */ };
— end example ]
2
[Note: The order of derivation is not significant except as specified by the semantics of initialization by
constructor (15.6.2), cleanup (15.4), and storage layout (12.2, 14.1).
— end note ]
3
A class shall not be specified as a direct base class of a derived class more than once. [Note: A class can
be an indirect base class more than once and can be a direct and an indirect base class. There are limited
things that can be done with such a class. The non-static data members and member functions of the direct
base class cannot be referred to in the scope of the derived class. However, the static members, enumerations
and types can be unambiguously referred to.
— end note ] [ Example:
class X { /* ... */ };
class Y : public X, public X { /* ... */ };
// ill-formed
class L { public: int next;
/* ... */ };
class A : public L { /* ... */ };
class B : public L { /* ... */ };
class C : public A, public B { void f(); /* ... */ };
// well-formed
class D : public A, public L { void f(); /* ... */ };
// well-formed
— end example ]
4
A base class specifier that does not contain the keyword virtual specifies a non-virtual base class. A base
class specifier that contains the keyword virtual specifies a virtual base class. For each distinct occurrence
of a non-virtual base class in the class lattice of the most derived class, the most derived object (6.6.2)
shall contain a corresponding distinct base class subobject of that type. For each distinct base class that is
specified virtual, the most derived object shall contain a single base class subobject of that type.
5
[Note: For an object of class type C, each distinct occurrence of a (non-virtual) base class L in the class
lattice of C corresponds one-to-one with a distinct L subobject within the object of type C. Given the class C
defined above, an object of class C will have two subobjects of class L as shown in Figure 3.
§ 13.1
228
L
L
A
B
C
Figure 3 — Non-virtual base
In such lattices, explicit qualification can be used to specify which subobject is meant. The body of function
C::f could refer to the member next of each L subobject:
void C::f() { A::next = B::next; }
// well-formed
Without the A:: or B:: qualifiers, the definition of C::f above would be ill-formed because of ambiguity (13.2).
— end note ]
6
[ Note: In contrast, consider the case with a virtual base class:
class V { /* ... */ };
class A : virtual public V { /* ... */ };
class B : virtual public V { /* ... */ };
class C : public A, public B { /* ... */ };
V
A
B
C
Figure 4 — Virtual base
For an object c of class type C, a single subobject of type V is shared by every base class subobject of c
that has a virtual base class of type V. Given the class C defined above, an object of class C will have one
subobject of class V, as shown in Figure 4.
— end note ]
7
[ Note: A class can have both virtual and non-virtual base classes of a given type.
class B { /* ... */ };
class X : virtual public B { /* ... */ };
class Y : virtual public B { /* ... */ };
class Z : public B { /* ... */ };
class AA : public X, public Y, public Z { /* ... */ };
For an object of class AA, all virtual occurrences of base class B in the class lattice of AA correspond to a
single B subobject within the object of type AA, and every other occurrence of a (non-virtual) base class B in
the class lattice of AA corresponds one-to-one with a distinct B subobject within the object of type AA. Given
the class AA defined above, class AA has two subobjects of class B: Z’s B and the virtual B shared by X and Y,
as shown in Figure 5.
— end note ]
13.2
Member name lookup
[class.member.lookup]
1
Member name lookup determines the meaning of a name (id-expression) in a class scope (6.3.7). Name lookup
can result in an ambiguity, in which case the program is ill-formed. For an id-expression, name lookup begins
in the class scope of this; for a qualified-id, name lookup begins in the scope of the nested-name-specifier.
Name lookup takes place before access control (6.4, Clause 14).
2
The following steps define the result of name lookup for a member name f in a class scope C.
§ 13.2
229
B
B
X
Y
Z
AA
Figure 5 — Virtual and non-virtual base
3
The lookup set for f in C, called S(f, C), consists of two component sets: the declaration set, a set of members
named f; and the subobject set, a set of subobjects where declarations of these members (possibly including
using-declarations) were found. In the declaration set, using-declarations are replaced by the set of designated
members that are not hidden or overridden by members of the derived class (10.3.3), and type declarations
(including injected-class-names) are replaced by the types they designate. S(f, C) is calculated as follows:
4
If C contains a declaration of the name f, the declaration set contains every declaration of f declared in C
that satisfies the requirements of the language construct in which the lookup occurs. [Note: Looking up a
name in an elaborated-type-specifier (6.4.4) or base-specifier (Clause 13), for instance, ignores all non-type
declarations, while looking up a name in a nested-name-specifier (6.4.3) ignores function, variable, and
enumerator declarations. As another example, looking up a name in a using-declaration (10.3.3) includes the
declaration of a class or enumeration that would ordinarily be hidden by another declaration of that name in
the same scope.
— end note ] If the resulting declaration set is not empty, the subobject set contains C itself,
and calculation is complete.
5
Otherwise (i.e., C does not contain a declaration of f or the resulting declaration set is empty), S(f,C) is
initially empty. If C has base classes, calculate the lookup set for f in each direct base class subobject Bi,
and merge each such lookup set S(f, Bi) in turn into S(f, C).
6
The following steps define the result of merging lookup set S(f, Bi) into the intermediate S(f, C):
(6.1)
If each of the subobject members of S(f, Bi) is a base class subobject of at least one of the subobject
members of S(f, C), or if S(f, Bi) is empty, S(f, C) is unchanged and the merge is complete. Conversely,
if each of the subobject members of S(f,C) is a base class subobject of at least one of the subobject
members of S(f, Bi), or if S(f, C) is empty, the new S(f, C) is a copy of S(f, Bi).
(6.2)
Otherwise, if the declaration sets of S(f,Bi) and S(f,C) differ, the merge is ambiguous: the new
S(f, C) is a lookup set with an invalid declaration set and the union of the subobject sets. In subsequent
merges, an invalid declaration set is considered different from any other.
(6.3)
Otherwise, the new S(f,C) is a lookup set with the shared set of declarations and the union of the
subobject sets.
7
The result of name lookup for f in C is the declaration set of S(f,C). If it is an invalid set, the program is
ill-formed. [ Example:
struct A { int x; };
// S(x,A) = { { A::x }, { A } }
struct B { float x; };
// S(x,B) = { { B::x }, { B } }
struct C: public A, public B { };
// S(x,C) = { invalid, { A in C, B in C } }
struct D: public virtual C { };
// S(x,D) = S(x,C)
struct E: public virtual C { char x; }; // S(x,E) = { { E::x }, { E } }
struct F: public D, public E { };
// S(x,F) = S(x,E)
int main() {
F f;
f.x = 0;
// OK, lookup finds E::x
}
S(x, F ) is unambiguous because the A and B base class subobjects of D are also base class subobjects of E, so
S(x, D) is discarded in the first merge step.
— end example ]
8
If the name of an overloaded function is unambiguously found, overload resolution (16.3) also takes place before
access control. Ambiguities can often be resolved by qualifying a name with its class name. [ Example:
§ 13.2
230
struct A {
int f();
};
struct B {
int f();
};
struct C : A, B {
int f() { return A::f() + B::f(); }
};
— end example ]
9
[Note: A static member, a nested type or an enumerator defined in a base class T can unambiguously be
found even if an object has more than one base class subobject of type T. Two base class subobjects share
the non-static member subobjects of their common virtual base classes.
— end note ] [ Example:
struct V {
int v;
};
struct A {
int a;
static int s;
enum { e };
};
struct B : A, virtual V { };
struct C : A, virtual V { };
struct D : B, C { };
void f(D* pd) {
pd->v++;
// OK: only one v (virtual)
pd->s++;
// OK: only one s (static)
int i = pd->e;
// OK: only one e (enumerator)
pd->a++;
// error, ambiguous: two as in D
}
— end example ]
10
[Note: When virtual base classes are used, a hidden declaration can be reached along a path through the
subobject lattice that does not pass through the hiding declaration. This is not an ambiguity. The identical
use with non-virtual base classes is an ambiguity; in that case there is no unique instance of the name that
hides all the others.
— end note ] [ Example:
struct V { int f(); int x; };
struct W { int g(); int y; };
struct B : virtual V, W {
int f(); int x;
int g(); int y;
};
struct C : virtual V, W { };
struct D : B, C { void glorp(); };
W
V
W
B
C
D
Figure 6 — Name lookup
The names declared in V and the left-hand instance of W are hidden by those in B, but the names declared in
the right-hand instance of W are not hidden at all.
§ 13.2
231

 

 

 

 

 

 

 

Content      ..     6      7      8      9     ..