C++中的[&]运算符

22

你好,我在Windows文档中找到了这段代码。

但我不明白它的含义。

[&]

请您帮我澄清一下它应该做什么?

这并不是符合C++标准的,对吗?

以下是代码:

void parallel_matrix_multiply(double** m1, double** m2, double** result, size_t size)
{
   parallel_for (size_t(0), size, [&](size_t i)
   {
      for (size_t j = 0; j < size; j++)
      {
         double temp = 0;
         for (int k = 0; k < size; k++)
         {
            temp += m1[i][k] * m2[k][j];
         }
         result[i][j] = temp;
      }
   });
}
6个回答

37

它介绍了一个lambda表达式。方括号中的内容指示lambda内要捕获什么。只有一个&表示在其范围之外找到的所有在lambda内提及的内容都会被引用捕获。

例如:

int a = 0;
auto l = [&]() { 
  ++a; // a refers to the a outside of this scope through a reference
}
l(); // execute the lambda

这是一个很好的例子...我喜欢函数内部的注释,它使&符号的含义更加清晰。 - FrankTan
如果我写 [=] 并编辑变量 a,那么在 lambda 函数外部该值会改变吗?还是因为没有通过引用传递而不会改变? - FrankTan
@frank: 如果你只是将&更改为=,它将无法编译,因为除非你使用mutable关键字明确表示你打算这样做,否则你不能修改复制的变量。 - sellibitze
谢谢你的回答,但是最后在 lambda 执行之后,如果 a 是可变的,那么它的值不会改变对吗? - FrankTan

22

它是C++11的功能,被称为lambda捕获子句。在这种情况下,[&]通过引用使parallel_matrix_multiply()函数的所有参数可供lambda函数使用。

有关更多信息,请参见lambda函数


使得parallel_matrix_multiply()函数的所有参数都可以通过引用传递给lambda函数。 - Steve Jessop
1
@SteveJessop,[&] 使得 lambda 函数体内所有变量都可以通过引用访问到,包括函数 parallel_matrix_multiply() 的参数。这是不正确的还是表述不清楚? - hmjd
就我理解而言,这是正确的(我不知道是否存在任何令人困惑的边缘情况)。我的评论只是试图让句子变得更加简洁明了,如果我没有传达清楚,那么很抱歉。 - Steve Jessop

10

这是C++11标准的一项特性。 lambda


10

这是用于 lambda 表达式的捕获子句。一个 lambda 表达式可以访问其封闭范围内的所有变量(即如果 lambda 函数在某个函数内部,它可以访问该函数内部的所有变量)。[&] 表示lambda将通过引用方式获取所有变量。它们也可以按值传递,在这种情况下,您将使用 [=]。 您还可以指定需要以特定方式获取的具体变量,例如以下代码:

[&X, =]

这意味着lambda将通过引用获取X变量,而其他所有变量都将通过值传递。


那么,如果我写 [=] 并编辑一个变量......然后在 lambda 函数外面,值会改变吗?我认为不会,对吧? - FrankTan
@Frank,是的,如果你写[=],lambda外部的值会保持不变,无论你做什么。 - SingerOfTheFall
这相当于将变量按值传递给常规函数:调用者的副本不会改变。您可以通过一个玩具示例轻松确认这一点。 - Useless
请纠正我,但是根据这里所述,lambda函数默认情况下无法访问其封闭作用域的变量。 - E. Kaufman

6

[&] 表示你可以在 lambda 表达式内部访问周围代码的变量,并且通过引用进行访问(即可以修改它们)。在示例代码中,您可以看到虽然没有将 m1、m2、resultsize 作为参数传递,但它们仍然被用于 lambda 表达式中。


3
从技术上讲,您无法在任何情况下修改变量,因为没有明确指定为“mutable”的lambda具有一个“const”“operator()”,因此捕获的变量无法更改。对于“mutable” lambda,变量可以在两种情况下更改,但是仅当通过引用捕获时,更改才会在lambda外部可见。 - Grizzly

4

这是一个Lambda函数,使用C++11特性

[&](size_t i){...}

将会像回调函数或函数对象一样起作用。因此,您不需要在其他地方编写另一个函数来传递给parallel_for。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接