|
1443 | 1443 | \pnum
|
1444 | 1444 | The result is the entity denoted by
|
1445 | 1445 | the \grammarterm{unqualified-id}\iref{basic.lookup.unqual}.
|
1446 |
| -If the entity is a local entity\iref{basic.pre} |
1447 |
| -and naming it from outside of an unevaluated operand |
1448 |
| -within the scope where the \grammarterm{unqualified-id} appears |
1449 |
| -would result in some intervening \grammarterm{lambda-expression} |
1450 |
| -capturing it by copy\iref{expr.prim.lambda.capture}, |
| 1446 | +If the \grammarterm{unqualified-id} appears |
| 1447 | +in a \grammarterm{lambda-expression} at program point $P$ and |
| 1448 | +the entity is a local entity\iref{basic.pre} or a variable declared by |
| 1449 | +an \grammarterm{init-capture}\iref{expr.prim.lambda.capture}, |
| 1450 | +then let $S$ be the \grammarterm{compound-expression} of |
| 1451 | +the innermost enclosing \grammarterm{lambda-expression} of $P$. |
| 1452 | +If naming the entity from outside of an unevaluated operand within $S$ |
| 1453 | +would refer to an entity |
| 1454 | +captured by copy in some intervening \grammarterm{lambda-expression}, |
| 1455 | +then let $E$ be the innermost such \grammarterm{lambda-expression}, and: |
| 1456 | +\begin{itemize} |
| 1457 | +\item |
| 1458 | +If $P$ is in $E$'s function parameter scope |
| 1459 | +but not its \grammarterm{parameter-declaration-clause}, then |
1451 | 1460 | the type of the expression is
|
1452 | 1461 | the type of a class member access expression\iref{expr.ref}
|
1453 | 1462 | naming the non-static data member
|
1454 | 1463 | that would be declared for such a capture
|
1455 |
| -in the object parameter\iref{dcl.fct} of the function call operator of |
1456 |
| -the innermost such intervening \grammarterm{lambda-expression}. |
| 1464 | +in the object parameter\iref{dcl.fct} of the function call operator of $E$. |
1457 | 1465 | \begin{note}
|
1458 |
| -If that \grammarterm{lambda-expression} is not declared \keyword{mutable}, |
| 1466 | +If $E$ is not declared \keyword{mutable}, |
1459 | 1467 | the type of such an identifier will typically be \keyword{const} qualified.
|
1460 | 1468 | \end{note}
|
| 1469 | +\item |
| 1470 | +Otherwise (if $P$ either precedes $E$'s function parameter scope or |
| 1471 | +is in $E$'s \grammarterm{parameter-declaration-clause}), |
| 1472 | +the program is ill-formed. |
| 1473 | +\end{itemize} |
1461 | 1474 | Otherwise, the type of the expression is the type of the result.
|
1462 | 1475 | \begin{note}
|
1463 | 1476 | If the entity is a template parameter object for
|
|
1477 | 1490 | \begin{codeblock}
|
1478 | 1491 | void f() {
|
1479 | 1492 | float x, &r = x;
|
1480 |
| - [=] { |
| 1493 | + [=]() -> decltype((x)) { // lambda returns \tcode{float const\&} because this lambda is not \tcode{mutable} and |
| 1494 | + // \tcode{x} is an lvalue |
1481 | 1495 | decltype(x) y1; // \tcode{y1} has type \tcode{float}
|
1482 |
| - decltype((x)) y2 = y1; // \tcode{y2} has type \tcode{float const\&} because this lambda |
1483 |
| - // is not \keyword{mutable} and \tcode{x} is an lvalue |
| 1496 | + decltype((x)) y2 = y1; // \tcode{y2} has type \tcode{float const\&} |
1484 | 1497 | decltype(r) r1 = y1; // \tcode{r1} has type \tcode{float\&}
|
1485 | 1498 | decltype((r)) r2 = y2; // \tcode{r2} has type \tcode{float const\&}
|
| 1499 | + return y2; |
| 1500 | + }; |
| 1501 | + |
| 1502 | + [=]<decltype(x) P>{}; // error: \tcode{x} refers to local entity but precedes the |
| 1503 | + // lambda's function parameter scope |
| 1504 | + [=](decltype((x)) y){}; // error: \tcode{x} refers to local entity but is in the lambda's |
| 1505 | + // \grammarterm{parameter-declaration-clause} |
| 1506 | + [=]{ |
| 1507 | + []<decltype(x) P>{}; // OK, \tcode{x} is in the outer lambda's function parameter scope |
| 1508 | + [](decltype((x)) y){}; // OK, lambda takes a parameter of type \tcode{float const\&} |
| 1509 | + [x=1](decltype((x)) z){}; // error: \tcode{x} refers to \grammarterm{init-capture} but is in the lambda's |
| 1510 | + // \grammarterm{parameter-declaration-clause} |
1486 | 1511 | };
|
1487 | 1512 | }
|
1488 | 1513 | \end{codeblock}
|
|
2197 | 2222 | \end{example}
|
2198 | 2223 |
|
2199 | 2224 | \pnum
|
2200 |
| -An \grammarterm{init-capture} inhabits the scope of |
2201 |
| -the \grammarterm{lambda-expression}'s \grammarterm{compound-statement}. |
| 2225 | +An \grammarterm{init-capture} inhabits the function parameter scope of |
| 2226 | +the \grammarterm{lambda-expression}'s \grammarterm{parameter-declaration-clause}. |
2202 | 2227 | An \grammarterm{init-capture} without ellipsis
|
2203 | 2228 | behaves as if it declares and explicitly captures a variable of
|
2204 | 2229 | the form ``\keyword{auto} \grammarterm{init-capture} \tcode{;}'', except that:
|
|
2224 | 2249 | }(); // Updates \tcode{::x} to 6, and initializes \tcode{y} to 7.
|
2225 | 2250 |
|
2226 | 2251 | auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
|
| 2252 | +auto counter = [i=0]() mutable -> decltype(i) { // OK, returns \tcode{int} |
| 2253 | + return i++; |
| 2254 | +}; |
2227 | 2255 | \end{codeblock}
|
2228 | 2256 | \end{example}
|
2229 | 2257 |
|
|
0 commit comments