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?
Class scope defines the accessibility or visibility of class variables or functions. The term scope is defined as a place where in variable name, function name and typedef are used inside a program.
Yes. unless, there is an ambiguity.
The using keyword is used to: Bring a specific member from the namespace into the current scope. Bring all members from the namespace into the current scope. Bring a base class method or variable into the current class's scope.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With