Стандарт C++ 11 (1119564), страница 31
Текст из файла (страница 31)
The result is themember. The type of the result is the type of the member. The result is an lvalue if the member is a staticmember function or a data member and a prvalue otherwise. [ Note: a class member can be referred to usinga qualified-id at any point in its potential scope (3.3.7). — end note ] Where class-name :: class-name isused, and the two class-names refer to the same class, this notation names the constructor (12.1).
Whereclass-name ::~ class-name is used, the two class-names shall refer to the same class; this notation namesthe destructor (12.4). The form ~ decltype-specifier also denotes the destructor, but it shall not be used asthe unqualified-id in a qualified-id. [ Note: a typedef-name that names a class is a class-name (9.1). — endnote ]9A ::, or a nested-name-specifier that names a namespace (7.3), in either case followed by the name of amember of that namespace (or the name of a member of a namespace made visible by a using-directive) is aqualified-id; 3.4.3.2 describes name lookup for namespace members that appear in qualified-ids. The resultis the member.
The type of the result is the type of the member. The result is an lvalue if the member is afunction or a variable and a prvalue otherwise.10A nested-name-specifier that denotes an enumeration (7.2), followed by the name of an enumerator of thatenumeration, is a qualified-id that refers to the enumerator. The result is the enumerator. The type of theresult is the type of the enumeration. The result is a prvalue.11In a qualified-id, if the unqualified-id is a conversion-function-id, its conversion-type-id shall denote the sametype in both the context in which the entire qualified-id occurs and in the context of the class denoted bythe nested-name-specifier.12An id-expression that denotes a non-static data member or non-static member function of a class can onlybe used:— as part of a class member access (5.2.5) in which the object expression refers to the member’s class61or a class derived from that class, or— to form a pointer to member (5.3.1), or— in a mem-initializer for a constructor for that class or for a class derived from that class (12.6.2), or— in a brace-or-equal-initializer for a non-static data member of that class or of a class derived from thatclass (12.6.2), or— if that id-expression denotes a non-static data member and it appears in an unevaluated operand.[ Example:61) This also applies when the object expression is an implicit (*this) (9.3.1).§ 5.1.1© ISO/IEC 2011 – All rights reserved91ISO/IEC 14882:2011(E)struct S {int m;};int i = sizeof(S::m);int j = sizeof(S::m + 42);// OK// OK— end example ]5.1.21Lambda expressions[expr.prim.lambda]Lambda expressions provide a concise way to create simple function objects.
[ Example:#include <algorithm>#include <cmath>void abssort(float *x, unsigned N) {std::sort(x, x + N,[](float a, float b) {return std::abs(a) < std::abs(b);});}— end example ]lambda-expression:lambda-introducer lambda-declaratoropt compound-statementlambda-introducer:[ lambda-captureopt ]lambda-capture:capture-defaultcapture-listcapture-default , capture-listcapture-default:&=capture-list:capture ...optcapture-list , capture ...optcapture:identifier& identifierthislambda-declarator:( parameter-declaration-clause ) mutableoptexception-specificationopt attribute-specifier-seqopt trailing-return-typeopt2The evaluation of a lambda-expression results in a prvalue temporary (12.2). This temporary is called theclosure object. A lambda-expression shall not appear in an unevaluated operand (Clause 5).
[ Note: Aclosure object behaves like a function object (20.8). — end note ]3The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type — called the closure type — whose properties are described below. This class type is notan aggregate (8.5.1). The closure type is declared in the smallest block scope, class scope, or namespacescope that contains the corresponding lambda-expression. [ Note: This determines the set of namespacesand classes associated with the closure type (3.4.2). The parameter types of a lambda-declarator do not§ 5.1.292© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)affect these associated namespaces and classes. — end note ] An implementation may define the closuretype differently from what is described below provided this does not alter the observable behavior of theprogram other than by changing:— the size and/or alignment of the closure type,— whether the closure type is trivially copyable (Clause 9),— whether the closure type is a standard-layout class (Clause 9), or— whether the closure type is a POD class (Clause 9).An implementation shall not add members of rvalue reference type to the closure type.4If a lambda-expression does not include a lambda-declarator, it is as if the lambda-declarator were ().
Ifa lambda-expression does not include a trailing-return-type, it is as if the trailing-return-type denotes thefollowing type:— if the compound-statement is of the form{ attribute-specifier-seqopt return expression ; }the type of the returned expression after lvalue-to-rvalue conversion (4.1), array-to-pointer conversion (4.2), and function-to-pointer conversion (4.3);— otherwise, void.[ Example:auto x1 = [](int i){ return i; }; // OK: return type is intauto x2 = []{ return { 1, 2 }; }; // error: the return type is void (a// braced-init-list is not an expression)— end example ]5The closure type for a lambda-expression has a public inline function call operator (13.5.4) whose parameters and return type are described by the lambda-expression’s parameter-declaration-clause and trailingreturn-type respectively.
This function call operator is declared const (9.3.1) if and only if the lambdaexpression’s parameter-declaration-clause is not followed by mutable. It is neither virtual nor declaredvolatile. Default arguments (8.3.6) shall not be specified in the parameter-declaration-clause of a lambdadeclarator. Any exception-specification specified on a lambda-expression applies to the corresponding functioncall operator. An attribute-specifier-seq in a lambda-declarator appertains to the type of the correspondingfunction call operator.
[ Note: Names referenced in the lambda-declarator are looked up in the context inwhich the lambda-expression appears. — end note ]6The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit constconversion function to pointer to function having the same parameter and return types as the closure type’sfunction call operator. The value returned by this conversion function shall be the address of a functionthat, when invoked, has the same effect as invoking the closure type’s function call operator.7The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator,but for purposes of name lookup (3.4), determining the type and value of this (9.3.2) and transforming idexpressions referring to non-static class members into class member access expressions using (*this) (9.3.1),the compound-statement is considered in the context of the lambda-expression.
[ Example:struct S1 {int x, y;int operator()(int);void f() {§ 5.1.2© ISO/IEC 2011 – All rights reserved93ISO/IEC 14882:2011(E)[=]()->int {return operator()(this->x + y); // equivalent to S1::operator()(this->x + (*this).y)// this has type S1*};}};— end example ]8If a lambda-capture includes a capture-default that is &, the identifiers in the lambda-capture shall not bepreceded by &. If a lambda-capture includes a capture-default that is =, the lambda-capture shall not containthis and each identifier it contains shall be preceded by &. An identifier or this shall not appear more thanonce in a lambda-capture.
[ Example:struct S2 { void f(int i); };void S2::f(int i) {[&, i]{ };// OK[&, &i]{ };// error: i preceded by & when & is the default[=, this]{ }; // error: this when = is the default[i, i]{ };// error: i repeated}— end example ]9A lambda-expression whose smallest enclosing scope is a block scope (3.3.3) is a local lambda expression; anyother lambda-expression shall not have a capture-list in its lambda-introducer.
The reaching scope of a locallambda expression is the set of enclosing scopes up to and including the innermost enclosing function andits parameters. [ Note: This reaching scope includes any intervening lambda-expressions. — end note ]10The identifiers in a capture-list are looked up using the usual rules for unqualified name lookup (3.4.1); eachsuch lookup shall find a variable with automatic storage duration declared in the reaching scope of the locallambda expression.
An entity (i.e. a variable or this) is said to be explicitly captured if it appears in thelambda-expression’s capture-list.11If a lambda-expression has an associated capture-default and its compound-statement odr-uses (3.2) thisor a variable with automatic storage duration and the odr-used entity is not explicitly captured, then theodr-used entity is said to be implicitly captured; such entities shall be declared within the reaching scope ofthe lambda expression. [ Note: The implicit capture of an entity by a nested lambda-expression can causeits implicit capture by the containing lambda-expression (see below). Implicit odr-uses of this can result inimplicit capture. — end note ]12An entity is captured if it is captured explicitly or implicitly.