Lambda的成员是如何初始化的?

Ita*_*iwa 2 lambda c++11

据说lambda的成员是在定义lambda时才初始化的,而不是在创建lambda的对象时初始化的。为了进一步了解这一点,我制作了一个函数foo,该函数可打印一条简单消息(稍后检查调用)并返回用于初始化lambda成员的整数值(任意值。此处为1024)。

在lambda主体内部,它打印其捕获对象的值。

int foo() {
    std::cout << "foo()" << std::endl;
    return 1024;
}

int main() {

    int x = 0;
    [x = foo()]()mutable{ x = foo();  cout << "in un-named lambda x: " << x << endl; };
}
Run Code Online (Sandbox Code Playgroud)

输出:

foo()
Run Code Online (Sandbox Code Playgroud)

为什么我得到foo()但没有得到:

foo()
foo()
in un-named lambda x: 1024
Run Code Online (Sandbox Code Playgroud)
  • 这是否意味着[x = foo()]初始化并且{x = foo()}是赋值?

bol*_*lov 5

因此,您的代码有两个问题:

  • int x = 0;

    x是永远不会使用。见下文

  • [x = foo()]

    这不捕捉变量xmain。相反,它是广义的lambda捕获。如果你要觉得在类类型相当于拉姆达的条款,它创建了一个名为成员x初始化所用foo()。同样,绝对与xmain中的变量没有关系。

  • [x = foo()]()mutable{ x = foo(); cout << "in un-named lambda x: " << x << endl; };

    最后,您的lambda永远不会被调用。所以{ x = foo(); cout << "in un-named lambda x: " << x << endl; }永远不会执行。

有一个很棒的工具,可让您查看编译器对代码的转换方式:https : //cppinsights.io/s/cd26f632

#include <iostream>

int foo()
{
  std::operator<<(std::cout, "foo()").operator<<(std::endl);
  return 1024;
}


int main()
{
  int x = 0;

  class __lambda_12_5
  {
    int x;
    public: 
    inline /*constexpr */ void operator()()
    {
      x = foo();
      std::operator<<(std::cout, "in un-named lambda x: ").operator<<(x).operator<<(std::endl);
    }

    public: __lambda_12_5(int _x)
    : x{_x}
    {}

  } __lambda_12_5{foo()};

  ;
}
Run Code Online (Sandbox Code Playgroud)

另外,请启用并注意您的警告:为什么我应该始终启用编译器警告?

source>:12:5: warning: expression result unused [-Wunused-value]

    [x = foo()]()mutable{ x = foo();  std::cout << "in un-named lambda x: " << x > << std::endl; };

    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~> ~~~~~~~~~~

<source>:11:9: warning: unused variable 'x' [-Wunused-variable]

    int x = 0;

        ^

2 warnings generated.
Run Code Online (Sandbox Code Playgroud)

如您所见,您将被告知未使用的变量和未调用的lambda。