Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the keyword `this` be used in the class scope?

Tags:

c++

c++11

lambda

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?

like image 944
Takatoshi Kondo Avatar asked Apr 27 '17 05:04

Takatoshi Kondo


People also ask

What are the scopes of the class?

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.

Is this keyword necessary in C++?

Yes. unless, there is an ambiguity.

What is the use of using keyword in C++?

​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.


1 Answers

Motivation to answer (by myself)

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.

Can the keyword 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.

Can the keyword 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.

Compiler implementation

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

like image 63
Takatoshi Kondo Avatar answered Nov 15 '22 04:11

Takatoshi Kondo