member-specification: member-declaration member-specification access-specifier : member-specification
member-declaration: attribute-specifier-seq decl-specifier-seq member-declarator-list ; 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-seq pure-specifier declarator brace-or-equal-initializer identifier attribute-specifier-seq : constant-expression
virt-specifier-seq: virt-specifier virt-specifier-seq virt-specifier
virt-specifier: override final
pure-specifier: = 0
struct S { using T = void(); T * p = 0; // OK: brace-or-equal-initializer virtual T f = 0; // OK: pure-specifier };
struct tnode { char tword[20]; int count; tnode* left; tnode* right; };
tnode s, *sp;declares s to be a tnode and sp to be a pointer to a tnode.
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; };
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 }
struct X { typedef int T; static T count; void f(T); }; void X::f(T t = count) { }
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;
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); }
struct s {
int a;
int f() const;
int g() { return a++; }
int h() const { return a++; } // error
};
int s::f() const { return a; }
struct process { static void reschedule(); }; process& g(); void f() { process::reschedule(); // OK: no object necessary g().reschedule(); // g() is called }
int g();
struct X {
static int g();
};
struct Y : X {
static int i;
};
int Y::i = g(); // equivalent to Y::g();
class process { static process* run_chain; static process* running; }; process* process::running = get_main(); process* process::run_chain = running;
identifier attribute-specifier-seq : constant-expressionspecifies a bit-field; its length is set off from the bit-field name by a colon.
enum BOOL { FALSE=0, TRUE=1 }; struct A { BOOL b:1; }; A a; void f() { a.b = TRUE; if (a.b == TRUE) // yields true { /* ... */ } }
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
struct enclose {
struct inner {
static int x;
void f(int i);
};
};
int enclose::inner::x = 1;
void enclose::inner::f(int i) { /* ... */ }
class E { class I1; // forward declaration of nested class class I2; class I1 { }; // definition of nested class }; class E::I2 { }; // definition of nested class
struct X { typedef int I; class Y { /* ... */ }; I a; }; I b; // error Y c; // error X::Y d; // OK X::I e; // OK