Reputation: 3550
It seems that I can define lambda expressions that capture this
in the class scope. As far as I read N4640 up to date working draft, I couldn't find the sentence that allows the behavior. I think that I'm missing something...
Here is an example:
#include <iostream>
#include <functional>
struct foo {
std::function<void()> f1 = [this]{ ++i; };
int i = 0;
};
int main() {
foo a;
foo const& cref = a;
cref.f1();
std::cout << a.i << std::endl;
}
Running demo. (g++ -std=c++11 pedantic) https://wandbox.org/permlink/HPzaOxbBkOQOmuS6
Updated
Thanks to @Brian and @cpplerner comments, I understand what my essential question is. That is "Is the keyword this
allowed to use in the class scope? not only non-static member function scope."
If it does, I can use this
in the lambda expression capture list in the class scope. It's very clear.
It seems that this
in the class scope regard as non-const pointer.
In order to solve my essential question, I read N4640 9.2.2.1 The this pointer [class.this]. It seems that it is allowed syntactically, but I couldn't find the semantic description. For non-static member functions, I found the semantic description at 9.2.2/3 and 9.2.2/4.
updated
I updated the title of the question to represent my essential question.
The original question title was Can lambda expression in the class scope capture this?
Upvotes: 6
Views: 214
Reputation: 3550
Thanks to the comments, my question is solved. I summarize the answer of the question using the comments for other people that see the question.
this
be used in the class scope?Yes. According to [expr.prim.this],
"The keyword this names a pointer to the object for which a non-static member function is invoked or a non-static data member's initializer ([class.mem]) is evaluated."
See @T.C 's comment.
this
be written in the capture list of the lambda expression in the class scope?No.
At least in the current draft of the C++ standard n4618, but C++ standard committee recognized as issue.
Here is the reason why this
is NOT permitted.
According to expr.prim.lambda,
"A lambda-expression whose smallest enclosing scope is a block scope is a *local lambda expression; any other lambda-expression shall not have a capture-default or simple-capture in its lambda-introducer."
A lambda-expression in the class scope is NOT a local lambda expression. Because a class scope is not a block scope. Here is a definition of the word block.
So the lambda-expression in the class scple shall not have capture-default or simple-capture in its lambda-introducer.
The keyword this
is one of simple-capture. See expr.prim.lambda.capture.
Hence, a lambda-expression that is in the class scope cannot capture this
.
See this @cpplearner 's comment and @T.C 's comment.
I tested the following code on g++ and clang++.
#include <iostream>
#include <functional>
struct foo {
std::function<void()> lambda_in_class_scope = [this]{
std::cout << this << std::endl;
};
};
int main() {
foo f;
std::cout << &f << std::endl;
f.lambda_in_class_scope();
}
Output:
0x7fff8f409cb0
0x7fff8f409cb0
I got the same address. This indicates that this
is captured correctly.
Here are running demos:
g++ 6.3 https://wandbox.org/permlink/FdhxJhVvripOQ1ng
clang++ 4.0 https://wandbox.org/permlink/kGoNBIoV5WTZV0sy
Upvotes: 1