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 requires-clause declarator brace-or-equal-initializer identifier attribute-specifier-seq : constant-expression brace-or-equal-initializer
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
}; — end 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
struct tnode {
char tword[20];
int count;
tnode* left;
tnode* right;
};
which contains an array of twenty characters, an integer, and two
pointers to objects of the same type.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; }; — end example
struct T1 { int a, b; };
struct T2 { int c; double d; };
union U { T1 t1; T2 t2; };
int f() {
U u = { { 1, 2 } }; // active member is t1
return u.t2.c; // OK, as if u.t1.a were nominated
} — end example
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 A { }; // implicitly declared A::operator=
struct B : A {
B& operator=(const B &);
};
B& B::operator=(const B& s) {
this->A::operator=(s); // well-formed
return *this;
} — end exampleptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq
struct S {
S(); // declares the constructor
};
S::S() { } // defines the constructor
— end example
struct C;
void no_opt(C*);
struct C {
int c;
C() : c(0) { no_opt(this); }
};
const C cobj;
void no_opt(C* cptr) {
int i = cobj.c * 100; // value of cobj.c is unspecified
cptr->c = 1;
cout << cobj.c * 100 // value of cobj.c is unspecified
<< '\n';
}
extern struct D d;
struct D {
D(int a) : a(a), b(d.a) {}
int a, b;
};
D d = D(1); // value of d.b is unspecified
— end example
struct X {
X(); // default constructor
X(X&); // copy constructor with a non-const parameter
};
const X cx;
X x = cx; // error: X::X(X&) cannot copy cx into x
— end example
struct S {
template<typename T> S(T);
S();
};
S g;
void h() {
S a(g); // does not instantiate the member template to produce S::S<S>(S);
// uses the implicitly declared copy constructor
} — end exampleX::X(const X&)
X::X(X&)
struct X {
X();
X& operator=(X&);
};
const X cx;
X x;
void f() {
x = cx; // error: X::operator=(X&) cannot assign cx into x
} — end exampleX& X::operator=(const X&)
X& X::operator=(X&)
struct S {
int a;
S& operator=(const S&) = default;
};
struct S {
int a;
S& operator=(const S&) = default;
S& operator=(S&&) = default;
}; — end exampleX& X::operator=(X&&);
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq
struct B {
virtual ~B() { }
};
struct D : B {
~D() { }
};
D D_object;
typedef B B_alias;
B* B_ptr = &D_object;
void f() {
D_object.B::~B(); // calls B's destructor
B_ptr->~B(); // calls D's destructor
B_ptr->~B_alias(); // calls D's destructor
B_ptr->B_alias::~B(); // calls B's destructor
B_ptr->B_alias::~B_alias(); // calls B's destructor
} — end example
void* operator new(std::size_t, void* p) { return p; }
struct X {
X(int);
~X();
};
void f(X* p);
void g() { // rare, specialized use:
char* buf = new char[sizeof(X)];
X* p = new(buf) X(222); // use buf[] and initialize
f(p);
p->X::~X(); // cleanup
}
struct X {
operator int();
};
struct Y {
operator X();
};
Y a;
int b = a; // error, a.operator X().operator int() not tried
int c = X(a); // OK: a.operator X().operator int()
— end example
struct X {
operator int();
};
struct Y : X {
operator char();
};
void f(Y& a) {
if (a) { // ill-formed: X::operator int() or Y::operator char()
}
} — end example
struct X {
X(int);
X(const char*, int =0);
X(int, int);
};
void f(X arg) {
X a = 1; // a = X(1)
X b = "Jessie"; // b = X("Jessie",0)
a = 2; // a = X(2)
f(3); // f(X(3))
f({1, 2}); // f(X(1,2))
} — end example
struct Z {
explicit Z();
explicit Z(int);
explicit Z(int, int);
};
Z a; // OK: default-initialization performed
Z b{}; // OK: direct initialization syntax used
Z c = {}; // error: copy-list-initialization
Z a1 = 1; // error: no implicit conversion
Z a3 = Z(1); // OK: direct initialization syntax used
Z a2(1); // OK: direct initialization syntax used
Z* p = new Z(1); // OK: direct initialization syntax used
Z a4 = (Z)1; // OK: explicit cast used
Z a5 = static_cast<Z>(1); // OK: explicit cast used
Z a6 = { 3, 4 }; // error: no implicit conversion
— end exampleconversion-function-id: operator conversion-type-id
conversion-type-id: type-specifier-seq conversion-declarator
conversion-declarator: ptr-operator conversion-declarator
class Y { };
struct Z {
explicit operator Y() const;
};
void h(Z z) {
Y y1(z); // OK: direct-initialization
Y y2 = z; // ill-formed: copy-initialization
Y y3 = (Y)z; // OK: cast notation
}
void g(X a, X b) {
int i = (a) ? 1+a : 0;
int j = (a&&b) ? a+b : i;
if (a) {
}
} — end example&ac.operator int*i; // syntax error: // parsed as: &(ac.operator int *)i // not as: &(ac.operator int)*i
operator int [[noreturn]] (); // error: noreturn attribute applied to a type
— end example
struct S {
operator auto() const { return 10; } // OK
template<class T>
operator auto() const { return 1.2; } // error: conversion function template
}; — end example
struct process {
static void reschedule();
};
process& g();
void f() {
process::reschedule(); // OK: no object necessary
g().reschedule(); // g() is called
} — end example
int g();
struct X {
static int g();
};
struct Y : X {
static int i;
};
int Y::i = g(); // equivalent to Y::g();
— end example
class process {
static process* run_chain;
static process* running;
};
process* process::running = get_main();
process* process::run_chain = running;identifier attribute-specifier-seq : constant-expression brace-or-equal-initializer
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
int x;
int y;
struct enclose {
int x;
static int s;
struct inner {
void f(int i) {
int a = sizeof(x); // OK: operand of sizeof is an unevaluated operand
x = i; // error: assign to enclose::x
s = i; // OK: assign to enclose::s
::x = i; // OK: assign to global x
y = i; // OK: assign to global y
}
void g(enclose* p, int i) {
p->x = i; // OK: assign to enclose::x
}
};
};
inner* p = 0; // error: inner not in scope
— end example
struct enclose {
struct inner {
static int x;
void f(int i);
};
};
int enclose::inner::x = 1;
void enclose::inner::f(int i) { /* ... */ } — end 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
struct X {
typedef int I;
class Y { /* ... */ };
I a;
};
I b; // error
Y c; // error
X::Y d; // OK
X::I e; // OK
— end example