可以在类范围中使用关键字"this"吗?

Tak*_*ndo 6 c++ lambda c++11

似乎我可以定义this在类范围内捕获的lambda表达式.至于我读N4640最新的工作草案,我找不到允许这种行为的句子.我想我错过了一些东西......

这是一个例子:

#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;
}
Run Code Online (Sandbox Code Playgroud)

运行演示.(g ++ -std = c ++ 11 pedantic) https://wandbox.org/permlink/HPzaOxbBkOQOmuS6

更新

感谢@Brian和@cpplerner的评论,我理解我的基本问题是什么.那就是"关键字是否this允许在类范围中使用?不仅仅是非静态成员函数范围." 如果是,我可以this在类范围的lambda表达式捕获列表中使用.很清楚.

似乎this在类范围内视为非const指针.

为了解决我的基本问题,我读了N4640 9.2.2.1这个指针[class.this].似乎它在语法上是允许的,但是我找不到语义描述.对于非静态成员函数,我在9.2.2/3和9.2.2/4中找到了语义描述.

更新

我更新了问题的标题以代表我的基本问题.

原来的问题标题是Can lambda表达式在类范围内捕获了吗?

Tak*_*ndo 1

回答动机(我自己)

感谢评论,我的问题解决了。我使用看到该问题的其他人的评论来总结该问题的答案。

关键字可以this在类范围内使用吗?

是的。根据[expr.prim.this]

“关键字 this 命名一个指向对象的指针,为该对象调用非静态成员函数或评估非静态数据成员的初始值设定项([class.mem])。”

请参阅@TC 的评论

关键字可以this写在类作用域的 lambda 表达式的捕获列表中吗?

不。

至少在当前的 C++ 标准草案n4618中,但 C++ 标准委员会承认这是一个问题

this这就是不允许的原因。

根据expr.prim.lambda

“最小封闭作用域是块作用域的lambda表达式是 *local lambda 表达式;任何其他lambda 表达式在其lambda-introducer中不应有capture-defaultsimple-capture。”

类作用域中的lambda 表达式不是本地lambda 表达式。因为类作用域不是块作用域这是单词block的定义。

因此,类 scple 中的lambda 表达式在其lambda-introducer中不应具有capture-defaultsimple-capture

关键字是simple-capturethis之一。请参阅expr.prim.lambda.capture

因此,类范围内的lambda 表达式this无法捕获.

请参阅@cpplearner 的评论@TC 的评论

编译器实现

我在 g++ 和 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();
}
Run Code Online (Sandbox Code Playgroud)

输出:

0x7fff8f409cb0
0x7fff8f409cb0
Run Code Online (Sandbox Code Playgroud)

我得到了相同的地址。这表明this捕获正确。

以下是运行演示:

g++ 6.3 https://wandbox.org/permlink/FdhxJhVvripOQ1ng

clang++ 4.0 https://wandbox.org/permlink/kGoNBIoV5WTZV0sy