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

时间:2017-04-27 05:23:15

标签: c++ c++11 lambda

似乎我可以定义在类范围内捕获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;
}

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

更新

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

似乎类范围中的this视为非const指针。

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

更新

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

原始问题标题是类范围内的lambda表达式是否可以捕获此内容?

1 个答案:

答案 0 :(得分:1)

回答的动机(由我自己)

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

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

是。根据{{​​3}},

&#34;关键字this指定一个指向调用了非静态成员函数的对象的指针,或者一个非静态数据成员的初始化程序([class.mem] ])被评估。&#34;

请参阅[expr.prim.this]

关键字this是否可以写入类范围中lambda表达式的捕获列表?

没有

至少在当前的C ++标准草案@T.C 's comment中,但C ++标准委员会认可为n4618

以下是不允许this的原因。

根据issue

&#34; lambda-expression ,其最小的封闭范围是块范围是*本地lambda表达式;任何其他 lambda-expression 在其 lambda-introducer 中不得有 capture-default simple-capture 。 &#34;

类范围中的 lambda-expression 不是本地lambda表达式。因为expr.prim.lambda不是class scope。以下是单词block scope的定义。

因此,类scple中的 lambda-expression 在其 lambda中不应具有 capture-default simple-capture 导引

关键字this simple-capture 之一。请参阅block

因此,类范围内的 lambda-expression 无法捕获this

请参阅此expr.prim.lambda.capture@cpplearner 's comment

编译器实现

我在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();
}

输出:

0x7fff8f409cb0
0x7fff8f409cb0

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

以下是正在运行的演示:

g ++ 6.3 @T.C 's comment

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