Стандарт C++ 11 (1119564), страница 57
Текст из файла (страница 57)
Similarly, the optional attribute-specifier-seq (7.6.1) appertains tothe pointer and not to the object pointed to.2[ Example: the declarationsconst int ci = 10, *pc = &ci, *const cpc = pc, **ppc;int i, *p, *const cp = &i;declare ci, a constant integer; pc, a pointer to a constant integer; cpc, a constant pointer to a constantinteger; ppc, a pointer to a pointer to a constant integer; i, an integer; p, a pointer to integer; and cp, aconstant pointer to integer. The value of ci, cpc, and cp cannot be changed after initialization. The valueof pc can be changed, and so can the object pointed to by cp. Examples of some correct operations arei = ci;*cp = ci;pc++;pc = cpc;pc = p;ppc = &pc;Examples of ill-formed operations areci = 1;ci++;*pc = 2;cp = &ci;cpc++;p = pc;ppc = &p;//////////////errorerrorerrorerrorerrorerrorerrorEach is unacceptable because it would either change the value of an object declared const or allow it to bechanged through a cv-unqualified pointer later, for example:*ppc = &ci;*p = 5;// OK, but would make p point to ci ...// ...
because of previous error// clobber ci— end example ]3See also 5.17 and 8.5.4[ Note: There are no pointers to references; see 8.3.2. Since the address of a bit-field (9.6) cannot be taken,a pointer can never point to a bit-field.
— end note ]8.3.21References[dcl.ref ]In a declaration T D where D has either of the forms& attribute-specifier-seqopt D1&& attribute-specifier-seqopt D1and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T,” then the type of theidentifier of D is “derived-declarator-type-list reference to T.” The optional attribute-specifier-seq appertainsto the reference type. Cv-qualified references are ill-formed except when the cv-qualifiers are introduced§ 8.3.2© ISO/IEC 2011 – All rights reserved187ISO/IEC 14882:2011(E)through the use of a typedef (7.1.3) or of a template type argument (14.3), in which case the cv-qualifiersare ignored. [ Example:typedef int& A;const A aref = 3;// ill-formed; lvalue reference to non-const initialized with rvalueThe type of aref is “lvalue reference to int”, not “lvalue reference to const int”.
— end example ] [ Note:A reference can be thought of as a name of an object. — end note ] A declarator that specifies the type“reference to cv void” is ill-formed.2A reference type that is declared using & is called an lvalue reference, and a reference type that is declaredusing && is called an rvalue reference. Lvalue references and rvalue references are distinct types. Exceptwhere explicitly noted, they are semantically equivalent and commonly referred to as references.3[ Example:void f(double& a) { a += 3.14; }// ...double d = 0;f(d);declares a to be a reference parameter of f so the call f(d) will add 3.14 to d.int v[20];// ...int& g(int i) { return v[i]; }// ...g(3) = 7;declares the function g() to return a reference to an integer so g(3)=7 will assign 7 to the fourth elementof the array v.
For another example,struct link {link* next;};link* first;void h(link*& p) {p->next = first;first = p;p = 0;}// p is a reference to pointervoid k() {link* q = new link;h(q);}declares p to be a reference to a pointer to link so h(q) will leave q with the value zero. See also 8.5.3.— end example ]4It is unspecified whether or not a reference requires storage (3.7).5There shall be no references to references, no arrays of references, and no pointers to references. Thedeclaration of a reference shall contain an initializer (8.5.3) except when the declaration contains an explicitextern specifier (7.1.1), is a class member (9.2) declaration within a class definition, or is the declaration§ 8.3.2188© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)of a parameter or a return type (8.3.5); see 3.1.
A reference shall be initialized to refer to a valid objector function. [ Note: in particular, a null reference cannot exist in a well-defined program, because the onlyway to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer,which causes undefined behavior. As described in 9.6, a reference cannot be bound directly to a bit-field.— end note ]6If a typedef (7.1.3), a type template-parameter (14.3.1), or a decltype-specifier (7.1.6.2) denotes a type TRthat is a reference to a type T, an attempt to create the type “lvalue reference to cv TR” creates the type“lvalue reference to T”, while an attempt to create the type “rvalue reference to cv TR” creates the type TR.[ Example:int i;typedef int& LRI;typedef int&& RRI;LRI& r1 = i;const LRI& r2 = i;const LRI&& r3 = i;// r1 has the type int&// r2 has the type int&// r3 has the type int&RRI& r4 = i;RRI&& r5 = 5;// r4 has the type int&// r5 has the type int&&decltype(r2)& r6 = i;decltype(r2)&& r7 = i;// r6 has the type int&// r7 has the type int&— end example ]8.3.31Pointers to members[dcl.mptr]In a declaration T D where D has the formnested-name-specifier * attribute-specifier-seqopt cv-qualifier-seqopt D1and the nested-name-specifier denotes a class, and the type of the identifier in the declaration T D1 is “deriveddeclarator-type-list T”, then the type of the identifier of D is “derived-declarator-type-list cv-qualifier-seq pointerto member of class nested-name-specifier of type T”.
The optional attribute-specifier-seq (7.6.1) appertains tothe pointer-to-member.2[ Example:struct X {void f(int);int a;};struct Y;int X::* pmi = &X::a;void (X::* pmf)(int) = &X::f;double X::* pmd;char Y::* pmc;declares pmi, pmf, pmd and pmc to be a pointer to a member of X of type int, a pointer to a member ofX of type void(int), a pointer to a member of X of type double and a pointer to a member of Y of typechar respectively. The declaration of pmd is well-formed even though X has no members of type double.Similarly, the declaration of pmc is well-formed even though Y is an incomplete type. pmi and pmf can beused like this:§ 8.3.3© ISO/IEC 2011 – All rights reserved189ISO/IEC 14882:2011(E)X obj;// ...obj.*pmi = 7;(obj.*pmf)(7);////////assign 7 to an integermember of objcall a function member of objwith the argument 7— end example ]3A pointer to member shall not point to a static member of a class (9.4), a member with reference type, or“cv void.”[ Note: See also 5.3 and 5.5.
The type “pointer to member” is distinct from the type “pointer”, that is, apointer to member is declared only by the pointer to member declarator syntax, and never by the pointerdeclarator syntax. There is no “reference-to-member” type in C++. — end note ]8.3.41Arrays[dcl.array]In a declaration T D where D has the formD1 [ constant-expressionopt ] attribute-specifier-seqoptand the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of theidentifier of D is an array type; if the type of the identifier of D contains the auto type-specifier, the programis ill-formed.
T is called the array element type; this type shall not be a reference type, the (possibly cvqualified) type void, a function type or an abstract class type. If the constant-expression (5.19) is present,it shall be an integral constant expression and its value shall be greater than zero. The constant expressionspecifies the bound of (number of elements in) the array. If the value of the constant expression is N, the arrayhas N elements numbered 0 to N-1, and the type of the identifier of D is “derived-declarator-type-list array of NT”. An object of array type contains a contiguously allocated non-empty set of N subobjects of type T.
Exceptas noted below, if the constant expression is omitted, the type of the identifier of D is “derived-declarator-typelist array of unknown bound of T”, an incomplete object type. The type “derived-declarator-type-list array ofN T” is a different type from the type “derived-declarator-type-list array of unknown bound of T”, see 3.9.
Anytype of the form “cv-qualifier-seq array of N T” is adjusted to “array of N cv-qualifier-seq T”, and similarly for“array of unknown bound of T”. The optional attribute-specifier-seq appertains to the array. [ Example:typedef int A[5], AA[2][3];typedef const A CA;typedef const AA CAA;// type is “array of 5 const int”// type is “array of 2 array of 3 const int”— end example ] [ Note: An “array of N cv-qualifier-seq T” has cv-qualified type; see 3.9.3. — end note ]2An array can be constructed from one of the fundamental types (except void), from a pointer, from a pointerto member, from a class, from an enumeration type, or from another array.3When several “array of” specifications are adjacent, a multidimensional array is created; only the first of theconstant expressions that specify the bounds of the arrays may be omitted.
In addition to declarations inwhich an incomplete object type is allowed, an array bound may be omitted in some cases in the declarationof a function parameter (8.3.5). An array bound may also be omitted when the declarator is followed by aninitializer (8.5). In this case the bound is calculated from the number of initial elements (say, N) supplied(8.5.1), and the type of the identifier of D is “array of N T.” Furthermore, if there is a preceding declarationof the entity in the same scope in which the bound was specified, an omitted array bound is taken to be thesame as in that earlier declaration, and similarly for the definition of a static data member of a class.4[ Example:float fa[17], *afp[17];§ 8.3.4190© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)declares an array of float numbers and an array of pointers to float numbers.