Стандарт C++ 98 (1119566), страница 23
Текст из файла (страница 23)
If E1 isan lvalue, then E1.E2 is an lvalue. Let the notation vq12 stand for the “union” of vq1 and vq2 ; that is,if vq1 or vq2 is volatile, then vq12 is volatile. Similarly, let the notation cq12 stand for the“union” of cq1 and cq2; that is, if cq1 or cq2 is const, then cq12 is const. If E2 is declared to be amutable member, then the type of E1.E2 is “vq12 T”. If E2 is not declared to be a mutable member, then the type of E1.E2 is “cq12 vq12 T”.— If E2 is a (possibly overloaded) member function, function overload resolution (13.3) is used to determine whether E1.E2 refers to a static or a non-static member function.— If it refers to a static member function, and the type of E2 is “function of (parameter type list)returning T”, then E1.E2 is an lvalue; the expression designates the static member function.
Thetype of E1.E2 is the same type as that of E2, namely “function of (parameter type list) returningT”.— Otherwise, if E1.E2 refers to a non-static member function, and the type of E2 is “function of(parameter type list) cv returning T”, then E1.E2 is not an lvalue. The expression designates anon-static member function. The expression can be used only as the left-hand operand of a memberfunction call (9.3).
[Note: any redundant set of parentheses surrounding the expression is ignored(5.1). ] The type of E1.E2 is “function of (parameter type list) cv returning T”.— If E2 is a nested type, the expression E1.E2 is ill-formed.— If E2 is a member enumerator, and the type of E2 is T, the expression E1.E2 is not an lvalue. Thetype of E1.E2 is T.5[Note: “class objects” can be structures (9.2) and unions (9.5).
Classes are discussed in clause 9. ]5.2.6 Increment and decrement[expr.post.incr]1The value obtained by applying a postfix ++ is the value that the operand had before applying the operator.[Note: the value obtained is a copy of the original value ] The operand shall be a modifiable lvalue. Thetype of the operand shall be an arithmetic type or a pointer to a complete object type. After the result isnoted, the value of the object is modified by adding 1 to it, unless the object is of type bool, in which caseit is set to true. [Note: this use is deprecated, see annex D.
] The result is an rvalue. The type of theresult is the cv-unqualified version of the type of the operand. See also 5.7 and 5.17.2The operand of postfix -- is decremented analogously to the postfix ++ operator, except that the operandshall not be of type bool. [Note: For prefix increment and decrement, see 5.3.2. ]__________________59) Note that if E1 has the type “pointer to class X”, then (*(E1)) is an lvalue.69ISO/IEC 14882:1998(E)© ISO/IEC5.2.7 Dynamic cast5 Expressions5.2.7 Dynamic cast[expr.dynamic.cast]1The result of the expression dynamic_cast<T>(v) is the result of converting the expression v to typeT. T shall be a pointer or reference to a complete class type, or “pointer to cv void”.
Types shall not bedefined in a dynamic_cast. The dynamic_cast operator shall not cast away constness (5.2.11).2If T is a pointer type, v shall be an rvalue of a pointer to complete class type, and the result is an rvalue oftype T. If T is a reference type, v shall be an lvalue of a complete class type, and the result is an lvalue ofthe type referred to by T.3If the type of v is the same as the required result type (which, for convenience, will be called R in thisdescription), or it is the same as R except that the class object type in R is more cv-qualified than the classobject type in v, the result is v (converted if necessary).4If the value of v is a null pointer value in the pointer case, the result is the null pointer value of type R.5If T is “pointer to cv1 B” and v has type “pointer to cv2 D” such that B is a base class of D, the result is apointer to the unique B sub-object of the D object pointed to by v.
Similarly, if T is “reference to cv1 B”and v has type “cv2 D” such that B is a base class of D, the result is an lvalue for the unique60) B sub-objectof the D object referred to by v. In both the pointer and reference cases, cv1 shall be the same cvqualification as, or greater cv-qualification than, cv2, and B shall be an accessible unambiguous base classof D. [Example:struct B {};struct D : B {};void foo(D* dp){B* bp = dynamic_cast<B*>(dp);}// equivalent to B* bp = dp;—end example]6Otherwise, v shall be a pointer to or an lvalue of a polymorphic type (10.3).7If T is “pointer to cv void,” then the result is a pointer to the most derived object pointed to by v.
Otherwise, a run-time check is applied to see if the object pointed or referred to by v can be converted to the typepointed or referred to by T.8The run-time check logically executes as follows:— If, in the most derived object pointed (referred) to by v, v points (refers) to a public base class subobject of a T object, and if only one object of type T is derived from the sub-object pointed (referred) toby v, the result is a pointer (an lvalue referring) to that T object.— Otherwise, if v points (refers) to a public base class sub-object of the most derived object, and thetype of the most derived object has an unambiguous public base class of type T, the result is a pointer(an lvalue referring) to the T sub-object of the most derived object.— Otherwise, the run-time check fails.9The value of a failed cast to pointer type is the null pointer value of the required result type.
A failed cast toreference type throws bad_cast (18.5.2).__________________60) The most derived object (1.8) pointed or referred to by v can contain other B objects as base classes, but these are ignored.70© ISO/IECISO/IEC 14882:1998(E)5 Expressions5.2.7 Dynamic cast[Example:class A { virtual void f(); };class B { virtual void g(); };class D : public virtual A, private B {};void g(){Dd;B* bp = (B*)&d;// cast needed to break protectionA* ap = &d;// public derivation, no cast neededD& dr = dynamic_cast<D&>(*bp);// failsap = dynamic_cast<A*>(bp);// failsbp = dynamic_cast<B*>(ap);// failsap = dynamic_cast<A*>(&d);// succeedsbp = dynamic_cast<B*>(&d);// fails}class E : public D, public B {};class F : public E, public D {};void h(){Ff;A* ap = &f;D* dp = dynamic_cast<D*>(ap);E*ep= (E*)ap;E*ep1 = dynamic_cast<E*>(ap);// succeeds: finds unique A// fails: yields 0// f has two D sub-objects// ill-formed:// cast from virtual base// succeeds}—end example] [Note: 12.7 describes the behavior of a dynamic_cast applied to an object under construction or destruction.
]5.2.8 Type identification[expr.typeid]1The result of a typeid expression is an lvalue of static type const std::type_info (18.5.1) anddynamic type const std::type_info or const name where name is an implementation-definedclass derived from std::type_info which preserves the behavior described in 18.5.1.61) The lifetimeof the object referred to by the lvalue extends to the end of the program. Whether or not the destructor iscalled for the type_info object at the end of the program is unspecified.2When typeid is applied to an lvalue expression whose type is a polymorphic class type (10.3), the resultrefers to a type_info object representing the type of the most derived object (1.8) (that is, the dynamictype) to which the lvalue refers. If the lvalue expression is obtained by applying the unary * operator to apointer62) and the pointer is a null pointer value (4.10), the typeid expression throws the bad_typeidexception (18.5.3).3When typeid is applied to an expression other than an lvalue of a polymorphic class type, the resultrefers to a type_info object representing the static type of the expression.
Lvalue-to-rvalue (4.1), arrayto-pointer (4.2), and function-to-pointer (4.3) conversions are not applied to the expression. If the type ofthe expression is a class type, the class shall be completely-defined. The expression is not evaluated.4When typeid is applied to a type-id, the result refers to a type_info object representing the type of thetype-id. If the type of the type-id is a reference type, the result of the typeid expression refers to atype_info object representing the referenced type.
If the type of the type-id is a class type or a referenceto a class type, the class shall be completely-defined. Types shall not be defined in the type-id.__________________61) The recommended name for such a class is extended_type_info.62) If p is an expression of pointer type, then *p, (*p), *(p), ((*p)), *((p)), and so on all meet this requirement.71ISO/IEC 14882:1998(E)© ISO/IEC5.2.8 Type identification55 ExpressionsThe top-level cv-qualifiers of the lvalue expression or the type-id that is the operand of typeid are alwaysignored. [Example:class D { ... };D d1;const D d2;typeid(d1)typeid(D)typeid(D)typeid(D)========typeid(d2);typeid(const D);typeid(d2);typeid(const D&);// yields true// yields true// yields true// yields true—end example]6If the header <typeinfo> (18.5.1) is not included prior to a use of typeid, the program is ill-formed.7[Note: 12.7 describes the behavior of typeid applied to an object under construction or destruction.
]5.2.9 Static cast[expr.static.cast]1The result of the expression static_cast<T>(v) is the result of converting the expression v to type T.If T is a reference type, the result is an lvalue; otherwise, the result is an rvalue. Types shall not be definedin a static_cast. The static_cast operator shall not cast away constness (5.2.11).2An expression e can be explicitly converted to a type T using a static_cast of the formstatic_cast<T>(e) if the declaration “T t(e);” is well-formed, for some invented temporary variable t (8.5).