为什么不允许使用=和this的lambda(但GCC接受)

Why is a lambda with = and this disallowed (yet GCC accepts)

本文关键字:lambda GCC 接受 this 不允许 为什么      更新时间:2023-10-16

我创建了一个简单的lambda,如下所示,它按预期工作(GCC 4.6.4和4.7.2-demo)。但后来我检查了标准,5.1.2-8明确禁止在lambda捕获中使用=this

如果lambda捕获包含捕获默认值,即=,则lambda捕获,并且它包含的每个标识符前面都应加上&。。

我是不是读错了什么,而这实际上是允许的(尽管这个例子明确显示这是禁止的)?如果没有,那么我很难理解为什么不允许这样做。同时,这是否意味着海湾合作委员会允许这样做是错误的?

#include <iostream>
#include <functional>
using namespace std;
struct sample {
    int a;
    std::function<int()> get_simple(int o) {
        return [=,this]() {
            return a + o;
        };
    }
};
int main() {
    sample s;
    auto f = s.get_simple(5);
    s.a = 10;
    cout << f() << endl; //prints 15 as expected
}

如果您已经通过设置[=]指定了默认捕获模式,则不需要捕获"this"字段。请参阅下面我明确传递"this"和o by值的地方。因此,警告告诉您,在这种情况下,您将多余地传递"this",因为当指定=或&作为默认捕获模式。因此,只有在未指定默认捕获模式时才指定"this"。请参见下文。

#include <iostream>
#include <functional>
using namespace std;
struct sample {
  int a;
  std::function<int()> get_simple(int o)
  {
   return [o,this]{ return a + o; };
  }
};
int main() {
  sample s;
  auto f = s.get_simple(5);
  s.a = 10;
  cout << f() << endl; //prints 15 as expected
}

使用GCC 4.8.1中编译的代码和-Wall标志,编译会发出以下警告:

main.cpp:在成员函数'std::function中sample::get_simple(int)':

main.cpp:10:19:警告:通过复制捕获"this"冗余显式通过复制捕获默认[默认启用]

     return [=,this]() {
               ^

我认为这是GCC为了与C++11之前的标准lambdas兼容而制作的。

P0409R2现在允许这样做。

此外,P0806R2不赞成使用[=]中的隐式this。例如,尝试Clang++8 -std=c++2a,您将收到[=]的警告[-Wrecommended this capture]。