这个指针是如何被捕获的?

时间:2014-01-14 16:27:20

标签: c++ c++11 lambda this

请考虑以下代码:

struct S
{
  int x;
  void f()
  {
    auto l = [&](){ x = 42; }; //this is implicitly captured here
  }
};

§5.1.2/ 14声明:

  

如果隐式捕获实体并且捕获默认值为=,或者使用不包含&的捕获明确捕获实体,则通过副本捕获实体。

因此我得出结论,this不是通过副本捕获的。但是后来§5.1.2/ 15:

  

如果实体被隐式或显式捕获但未被副本捕获,则通过引用捕获该实体。未指定是否在闭包类型中为通过引用捕获的实体声明了其他未命名的非静态数据成员。

this 通过引用捕获。但现在§5.1.2/ 17表示:

  

[...]如果捕获this,则this的每个odr-use都会转换为对闭包类型的相应未命名数据成员的访问,[...]

据我所知,这意味着闭包类型中必须有一个与this指针对应的未命名数据成员。但由于this 通过引用捕获,因此标准不要求存在此类成员。我有什么问题?

3 个答案:

答案 0 :(得分:1)

该标准很难说清楚,但this只能通过复制来捕获。它不可能被左值引用捕获,因为this是每个C ++11§9.3.2/ 1的右值。

请注意,标准禁止通过引用显式捕获this,因为(a)语法在捕获列表中不允许&this,因为this在词法上是关键字而不是标识符,以及(b)5.1.2 / 8禁止在捕获默认值为this时显式捕获=

规范中似乎是错误,当捕获默认值为this时,可以隐式捕获&,表明它是通过引用捕获的。

答案 1 :(得分:0)

我认为你发现了一个规范错误 - 你是正确的,this是通过引用捕获的,但你在§5.1.2/ 17中找到的文本只应适用于{{1}通过复制捕获。

正如Casey所说,通过引用捕获this并没有多大意义。

答案 2 :(得分:0)

当然这种数据成员存在于闭包类型中。按值捕获并通过引用捕获都需要闭包类型中的数据成员。唯一的问题是它的类型:

T /* maybe const and/or volatile */ * captured_this;

VS

T /* maybe const and/or volatile */ * const & captured_this;

由于this无法改变,因此两者之间没有可观察到的差异。