Стандарт C++ 11 (1119564), страница 30
Текст из файла (страница 30)
Relationsbetween operators, such as ++a meaning a+=1, are not guaranteed for overloaded operators (13.5), and arenot guaranteed for operands of type bool. — end note ]3Clause 5 defines the effects of operators when applied to types for which they have not been overloaded.Operator overloading shall not modify the rules for the built-in operators, that is, for operators applied totypes for which they are defined by this Standard. However, these built-in operators participate in overloadresolution, and as part of that process user-defined conversions will be considered where necessary to convertthe operands to types appropriate for the built-in operator.
If a built-in operator is selected, such conversionswill be applied to the operands before the operation is considered further according to the rules in Clause 5;see 13.3.1.2, 13.6.4If during the evaluation of an expression, the result is not mathematically defined or not in the range ofrepresentable values for its type, the behavior is undefined.
[ Note: most existing implementations of C++ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, and allfloating point exceptions vary among machines, and is usually adjustable by a library function. — end note ]5If an expression initially has the type “reference to T” (8.3.2, 8.5.3), the type is adjusted to T prior toany further analysis. The expression designates the object or function denoted by the reference, and theexpression is an lvalue or an xvalue, depending on the expression.6[ Note: An expression is an xvalue if it is:— the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue referenceto object type,— a cast to an rvalue reference to object type,— a class member access expression designating a non-static data member of non-reference type in whichthe object expression is an xvalue, or— a .* pointer-to-member expression in which the first operand is an xvalue and the second operand isa pointer to data member.In general, the effect of this rule is that named rvalue references are treated as lvalues and unnamed rvaluereferences to objects are treated as xvalues; rvalue references to functions are treated as lvalues whethernamed or not.
— end note ][ Example:struct A {int m;58) The precedence of operators is not directly specified, but it can be derived from the syntax.© ISO/IEC 2011 – All rights reserved87ISO/IEC 14882:2011(E)};A&& operator+(A, A);A&& f();A a;A&& ar = static_cast<A&&>(a);The expressions f(), f().m, static_cast<A&&>(a), and a + a are xvalues. The expression ar is an lvalue.— end example ]7In some contexts, unevaluated operands appear (5.2.8, 5.3.3, 5.3.7, 7.1.6.2). An unevaluated operand is notevaluated.
[ Note: In an unevaluated operand, a non-static class member may be named (5.1) and namingof objects or functions does not, by itself, require that a definition be provided (3.2). — end note ]8Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand,the lvalue-to-rvalue (4.1), array-to-pointer (4.2), or function-to-pointer (4.3) standard conversions are appliedto convert the expression to a prvalue. [ Note: because cv-qualifiers are removed from the type of anexpression of non-class type when the expression is converted to a prvalue, an lvalue expression of typeconst int can, for example, be used where a prvalue expression of type int is required.
— end note ]9Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yieldresult types in a similar way. The purpose is to yield a common type, which is also the type of the result.This pattern is called the usual arithmetic conversions, which are defined as follows:— If either operand is of scoped enumeration type (7.2), no conversions are performed; if the otheroperand does not have the same type, the expression is ill-formed.— If either operand is of type long double, the other shall be converted to long double.— Otherwise, if either operand is double, the other shall be converted to double.— Otherwise, if either operand is float, the other shall be converted to float.— Otherwise, the integral promotions (4.5) shall be performed on both operands.59 Then the followingrules shall be applied to the promoted operands:— If both operands have the same type, no further conversion is needed.— Otherwise, if both operands have signed integer types or both have unsigned integer types, theoperand with the type of lesser integer conversion rank shall be converted to the type of theoperand with greater rank.— Otherwise, if the operand that has unsigned integer type has rank greater than or equal to therank of the type of the other operand, the operand with signed integer type shall be converted tothe type of the operand with unsigned integer type.— Otherwise, if the type of the operand with signed integer type can represent all of the values ofthe type of the operand with unsigned integer type, the operand with unsigned integer type shallbe converted to the type of the operand with signed integer type.— Otherwise, both operands shall be converted to the unsigned integer type corresponding to thetype of the operand with signed integer type.59) As a consequence, operands of type bool, char16_t, char32_t, wchar_t, or an enumerated type are converted to someintegral type.88© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)10In some contexts, an expression only appears for its side effects.
Such an expression is called a discarded-valueexpression. The expression is evaluated and its value is discarded. The array-to-pointer (4.2) and functionto-pointer (4.3) standard conversions are not applied. The lvalue-to-rvalue conversion (4.1) is applied onlyif the expression is an lvalue of volatile-qualified type and it has one of the following forms:— id-expression (5.1.1),— subscripting (5.2.1),— class member access (5.2.5),— indirection (5.3.1),— pointer-to-member operation (5.5),— conditional expression (5.16) where both the second and the third operands are one of the above, or— comma expression (5.18) where the right operand is one of the above.11The values of the floating operands and the results of floating expressions may be represented in greaterprecision and range than that required by the type; the types are not changed thereby.605.1Primary expressions5.1.1General[expr.prim][expr.prim.general]primary-expression:literalthis( expression )id-expressionlambda-expressionid-expression:unqualified-idqualified-idunqualified-id:identifieroperator-function-idconversion-function-idliteral-operator-id~ class-name~ decltype-specifiertemplate-id1A literal is a primary expression.
Its type depends on its form (2.14). A string literal is an lvalue; all otherliterals are prvalues.2The keyword this names a pointer to the object for which a non-static member function (9.3.2) is invokedor a non-static data member’s initializer (9.2) is evaluated.3If a declaration declares a member function or member function template of a class X, the expression thisis a prvalue of type “pointer to cv-qualifier-seq X” between the optional cv-qualifer-seq and the end of thefunction-definition, member-declarator, or declarator.
It shall not appear before the optional cv-qualifier-seqand it shall not appear within the declaration of a static member function (although its type and valuecategory are defined within a static member function as they are within a non-static member function).60) The cast and assignment operators must still perform their specific conversions as described in 5.4, 5.2.9 and 5.17.§ 5.1.1© ISO/IEC 2011 – All rights reserved89ISO/IEC 14882:2011(E)[ Note: this is because declaration matching does not occur until the complete declarator is known.
—end note ] Unlike the object expression in other contexts, *this is not required to be of complete type forpurposes of class member access (5.2.5) outside the member function body. [ Note: only class membersdeclared prior to the declaration are visible. — end note ] [ Example:struct A {char g();template<class T> auto f(T t) -> decltype(t + g()){ return t + g(); }};template auto A::f(int t) -> decltype(t + g());— end example ]4Otherwise, if a member-declarator declares a non-static data member (9.2) of a class X, the expression thisis a prvalue of type “pointer to X” within the optional brace-or-equal-initializer.
It shall not appear elsewherein the member-declarator.5The expression this shall not appear in any other context. [ Example:class Outer {int a[sizeof(*this)];unsigned int sz = sizeof(*this);void f() {int b[sizeof(*this)];struct Inner {int c[sizeof(*this)];};// error: not inside a member function// OK: in brace-or-equal-initializer// OK// error: not inside a member function of Inner}};— end example ]6A parenthesized expression is a primary expression whose type and value are identical to those of theenclosed expression. The presence of parentheses does not affect whether the expression is an lvalue.
Theparenthesized expression can be used in exactly the same contexts as those where the enclosed expressioncan be used, and with the same meaning, except as otherwise indicated.7An id-expression is a restricted form of a primary-expression. [ Note: an id-expression can appear after .and -> operators (5.2.5). — end note ]8An identifier is an id-expression provided it has been suitably declared (Clause 7). [ Note: for operatorfunction-ids, see 13.5; for conversion-function-ids, see 12.3.2; for literal-operator-ids, see 13.5.8; for templateids, see 14.2.
A class-name or decltype-specifier prefixed by ~ denotes a destructor; see 12.4. Within thedefinition of a non-static member function, an identifier that names a non-static member is transformed to aclass member access expression (9.3.1). — end note ] The type of the expression is the type of the identifier.The result is the entity denoted by the identifier. The result is an lvalue if the entity is a function, variable,or data member and a prvalue otherwise.§ 5.1.190© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)qualified-id:nested-name-specifier templateopt unqualified-id:: identifier:: operator-function-id:: literal-operator-id:: template-idnested-name-specifier:::opt type-name ::::opt namespace-name ::decltype-specifier ::nested-name-specifier identifier ::nested-name-specifier templateopt simple-template-id ::A nested-name-specifier that denotes a class, optionally followed by the keyword template (14.2), and thenfollowed by the name of a member of either that class (9.2) or one of its base classes (Clause 10), is aqualified-id; 3.4.3.1 describes name lookup for class members that appear in qualified-ids.