Skip to content

Commit 3a9bf2e

Browse files
Dawn Perchikzygoloid
authored andcommitted
P0018R3 Lambda Capture of *this by Value as [=,*this]
Editorially fixed punctuation and formatting, and used bullets for the change to 5.1.2/15.
1 parent 2c492b8 commit 3a9bf2e

File tree

2 files changed

+75
-42
lines changed

2 files changed

+75
-42
lines changed

source/basic.tex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
\indextext{region!declarative}%
3333
\indextext{entity}%
3434
An \defn{entity} is a value, object, reference, function, enumerator, type,
35-
class member, bit-field, template, template specialization, namespace, parameter
36-
pack, or \tcode{this}.
35+
class member, bit-field, template, template specialization, namespace, or
36+
parameter pack.
3737

3838
\pnum
3939
A \defn{name} is a use of an \grammarterm{identifier}~(\ref{lex.name}),

source/expressions.tex

Lines changed: 73 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@
621621
identifier\br
622622
\terminal{\&} identifier\br
623623
\terminal{this}
624+
\terminal{* this}
624625
\end{bnf}
625626

626627
\begin{bnf}
@@ -866,18 +867,23 @@
866867
by \tcode{\&}. If a \grammarterm{lambda-capture} includes a
867868
\grammarterm{capture-default} that is \tcode{=}, each
868869
\grammarterm{simple-capture} of that \grammarterm{lambda-capture} shall
869-
be of the form ``\tcode{\&} \grammarterm{identifier}''. Ignoring appearances in
870+
be of the form ``\tcode{\&} \grammarterm{identifier}'' or ``\tcode{* this}''.
871+
\enternote The form \tcode{[\&,this]} is redundant but accepted
872+
for compatibility with ISO \Cpp14. \exitnote
873+
Ignoring appearances in
870874
\grammarterm{initializer}{s} of \grammarterm{init-capture}{s}, an identifier or
871875
\tcode{this} shall not appear more than once in a
872876
\grammarterm{lambda-capture}. \enterexample
873877

874878
\begin{codeblock}
875879
struct S2 { void f(int i); };
876880
void S2::f(int i) {
877-
[&, i]{ }; // OK
878-
[&, &i]{ }; // error: \tcode{i} preceded by \tcode{\&} when \tcode{\&} is the default
879-
[=, this]{ }; // error: \tcode{this} when \tcode{=} is the default
880-
[i, i]{ }; // error: \tcode{i} repeated
881+
[&, i]{ }; // OK
882+
[&, &i]{ }; // error: \tcode{i} preceded by \tcode{\&} when \tcode{\&} is the default
883+
[=, *this]{ }; // OK
884+
[=, this]{ }; // error: \tcode{this} when \tcode{=} is the default
885+
[i, i]{ }; // error: \tcode{i} repeated
886+
[this, *this]{ }; // error: \tcode{this} appears twice
881887
}
882888
\end{codeblock}
883889
\exitexample
@@ -897,7 +903,9 @@
897903
usual rules for unqualified name lookup~(\ref{basic.lookup.unqual}); each such lookup
898904
shall find an entity. An entity that is designated by a
899905
\grammarterm{simple-capture}
900-
is said to be \defn{explicitly captured}, and shall be \tcode{this} or
906+
is said to be \defn{explicitly captured}, and shall be \tcode{*this}
907+
(when the \grammarterm{simple-capture}
908+
is ``\tcode{this}'' or ``\tcode{* this}'') or
901909
a variable with automatic storage duration declared in
902910
the reaching scope of the local lambda expression.
903911

@@ -932,15 +940,17 @@
932940

933941
\pnum
934942
A \grammarterm{lambda-expression} with an associated
935-
\grammarterm{capture-default} that does not explicitly capture \tcode{this} or
943+
\grammarterm{capture-default} that does not explicitly capture \tcode{*this} or
936944
a variable with automatic storage duration (this excludes any \grammarterm{id-expression}
937945
that has been found to refer to an \grammarterm{init-capture}{'s} associated
938946
\indextext{implicit capture!definition of}%
939947
non-static data member), is said to \defnx{implicitly capture}{capture!implicit}
940948
the entity (i.e.,
941-
\tcode{this} or a variable) if the \grammarterm{compound-statement}:
949+
\tcode{*this} or a variable) if the \grammarterm{compound-statement}:
942950
\begin{itemize}
943-
\item odr-uses~(\ref{basic.def.odr}) the entity, or
951+
\item odr-uses~(\ref{basic.def.odr}) the entity (in the case of a variable),
952+
\item odr-uses~(\ref{basic.def.odr}) \tcode{this}
953+
(in the case of the object designated by \tcode{*this}), or
944954
\item names the entity in a potentially-evaluated
945955
expression~(\ref{basic.def.odr}) where the enclosing full-expression depends on
946956
a generic lambda parameter declared within the reaching scope of the
@@ -973,7 +983,7 @@
973983
\pnum
974984
An entity is \defn{captured} if it is captured explicitly or implicitly. An entity
975985
captured by a \grammarterm{lambda-expression} is odr-used~(\ref{basic.def.odr}) in the scope
976-
containing the \grammarterm{lambda-expression}. If \tcode{this} is captured by a local
986+
containing the \grammarterm{lambda-expression}. If \tcode{*this} is captured by a local
977987
lambda expression, its nearest enclosing function shall be a non-static member function.
978988
If a \grammarterm{lambda-expression} or an instantiation of the function call
979989
operator template of a generic lambda odr-uses~(\ref{basic.def.odr}) \tcode{this} or a
@@ -1012,6 +1022,22 @@
10121022
}
10131023
};
10141024
}
1025+
1026+
struct s2 {
1027+
double ohseven = .007;
1028+
auto f() {
1029+
return [this] {
1030+
return [*this] {
1031+
return ohseven; // OK
1032+
}
1033+
}();
1034+
}
1035+
auto g() {
1036+
return [] {
1037+
return [*this] { }; // error: \tcode{*this} not captured by outer \grammarterm{lambda-expression}
1038+
}();
1039+
}
1040+
};
10151041
\end{codeblock}
10161042
\exitexample
10171043

@@ -1032,10 +1058,18 @@
10321058
\exitexample
10331059

10341060
\pnum
1035-
An entity is \defnx{captured by copy}{captured!by~copy} if it is implicitly captured and the
1036-
\grammarterm{capture-default} is \tcode{=} or if it is explicitly captured with a
1037-
capture that is not of the form \tcode{\&} \grammarterm{identifier} or
1061+
An entity is \defnx{captured by copy}{captured!by~copy} if
1062+
\begin{itemize}
1063+
\item
1064+
it is implicitly captured,
1065+
the \grammarterm{capture-default} is \tcode{=}, and
1066+
the captured entity is not \tcode{*this}, or
1067+
\item
1068+
it is explicitly captured with a capture that is not of the form
1069+
\tcode{this},
1070+
\tcode{\&} \grammarterm{identifier}, or
10381071
\tcode{\&} \grammarterm{identifier} \grammarterm{initializer}.
1072+
\end{itemize}
10391073
For each entity captured by copy, an
10401074
unnamed non-static data member is declared in the closure type. The declaration order of
10411075
these members is unspecified. The type of such a data member is the type of the
@@ -1044,6 +1078,32 @@
10441078
function, the corresponding data member is also a reference to a function. \exitnote
10451079
A member of an anonymous union shall not be captured by copy.
10461080

1081+
\pnum
1082+
Every \grammarterm{id-expression} within the \grammarterm{compound-statement} of a
1083+
\grammarterm{lambda-expression} that is an odr-use~(\ref{basic.def.odr}) of an
1084+
entity captured by copy is transformed into an access to the corresponding unnamed data
1085+
member of the closure type.
1086+
\enternote An \grammarterm{id-expression} that is not an odr-use refers to
1087+
the original entity, never to a member of the closure type. Furthermore, such
1088+
an \grammarterm{id-expression} does not cause the implicit capture of the
1089+
entity. \exitnote
1090+
If \tcode{*this} is captured by copy, each odr-use of \tcode{this} is
1091+
transformed into a pointer to the corresponding unnamed data member of the closure type,
1092+
cast~(\ref{expr.cast}) to the type of \tcode{this}. \enternote The cast ensures that the
1093+
transformed expression is a prvalue. \exitnote \enterexample
1094+
\begin{codeblock}
1095+
void f(const int*);
1096+
void g() {
1097+
const int N = 10;
1098+
[=] {
1099+
int arr[N]; // OK: not an odr-use, refers to automatic variable
1100+
f(&N); // OK: causes \tcode{N} to be captured; \tcode{\&N} points to the
1101+
// corresponding member of the closure type
1102+
};
1103+
}
1104+
\end{codeblock}
1105+
\exitexample
1106+
10471107
\pnum
10481108
An entity is \defnx{captured by reference}{captured!by~reference} if it is implicitly or explicitly
10491109
captured but not captured by copy. It is unspecified whether additional unnamed
@@ -1083,33 +1143,6 @@
10831143
\end{codeblock}
10841144
\exitexample
10851145

1086-
1087-
\pnum
1088-
Every \grammarterm{id-expression} within the \grammarterm{compound-statement} of a
1089-
\grammarterm{lambda-expression} that is an odr-use~(\ref{basic.def.odr}) of an
1090-
entity captured by copy is transformed into an access to the corresponding unnamed data
1091-
member of the closure type.
1092-
\enternote An \grammarterm{id-expression} that is not an odr-use refers to
1093-
the original entity, never to a member of the closure type. Furthermore, such
1094-
an \grammarterm{id-expression} does not cause the implicit capture of the
1095-
entity. \exitnote
1096-
If \tcode{this} is captured, each odr-use of \tcode{this} is
1097-
transformed into an access to the corresponding unnamed data member of the closure type,
1098-
cast~(\ref{expr.cast}) to the type of \tcode{this}. \enternote The cast ensures that the
1099-
transformed expression is a prvalue. \exitnote \enterexample
1100-
\begin{codeblock}
1101-
void f(const int*);
1102-
void g() {
1103-
const int N = 10;
1104-
[=] {
1105-
int arr[N]; // OK: not an odr-use, refers to automatic variable
1106-
f(&N); // OK: causes \tcode{N} to be captured; \tcode{\&N} points to the
1107-
// corresponding member of the closure type
1108-
};
1109-
}
1110-
\end{codeblock}
1111-
\exitexample
1112-
11131146
\pnum
11141147
Every occurrence of \tcode{decltype((x))} where \tcode{x} is a possibly
11151148
parenthesized \grammarterm{id-expression} that names an entity of automatic storage

0 commit comments

Comments
 (0)