代码"[&]()"在 c++ 中是什么意思?

What does the code `[&]()` mean in c++?

本文关键字:c++ 是什么 意思 代码      更新时间:2023-10-16

我正在为DirectX应用程序寻找Visual Studio模板。我遇到了m_time.Tick([&]() { ... });,我不知道[&]()部分是什么意思。我甚至不确定这是不是一个愚蠢的问题,因为我对c++相当缺乏经验。

我知道[]用于lambda表达式,但我不确定这是否有意义。也许是一些奇怪的委托用语?我都不知道。

如果您能给我指一列我在尝试学习c++时可能遇到的其他晦涩的习语,我将非常感激。

这是一个lambda函数的例子。

c++充满了晦涩的角落,但由于语法奇怪,lambda函数非常值得学习。声明lambda函数的基本语法是[]() { }。这是一个表达式,其结果是一个实现定义类型的对象,可以像调用函数一样调用它(因为,在lambda表达式语法的编译器实现中,它是一个函数)。

这样做的第一个好处是,函数可以与其他代码内嵌声明,而不必分开声明(这对于非常短的或特定用途的函数通常是不方便的)。

然而,lambda表达式最强大的部分是它们能够从周围的上下文中捕获变量:这就是示例代码中的&所做的。用[&]声明的lambda通过引用捕获所有变量(如果在方法中使用,则捕获隐式this指针)。(也有[=]按值捕获,甚至扩展语法以特定方式捕获特定变量。) 简而言之,这段代码:
m_time.Tick([&]() { ... });

调用m_time对象上的Tick方法,并传递给它一个lambda函数,该函数通过引用捕获周围的上下文。大概,Tick方法会在执行期间调用这个lambda函数。在...中,可以使用声明lambda的作用域中可用的变量——这种捕获能力是lambda最强大、最方便的特性。

选自c++入门

[&]隐式引用捕获列表。在lambda主体中使用的封闭函数的实体由引用

使用

因此,实际上,可以将[&]() {...}表达式看作是一个语句,表示您希望对在包含范围内声明的所有变量的引用在lambda表达式中可用。例如…

#include <iostream>
int main(int argc, char** argv) {
    int x = 0;
    int y = 1;
    auto f1 = [&] () { std::cout << x << std::endl; }
    auto f2 = [&x] () { std::cout << x << std::endl; }
    auto f3 = [x] () { std::cout << x << std::endl; }
    ++x;
    f1();
    f2();
    f3();
}
  • f1将打印1
  • f2将打印1
  • f3将打印0

f1f2的区别在于,f1捕获了xy的引用,而f2只捕获了x的引用。另一方面,f3在定义时捕获x的值(在本例中为0)。由于f1f2都捕获了对x的引用,因此在x增加后调用它们时都将打印1。但是,由于f3在定义时捕获了x的值,因此f3将打印0。

这是lambda表达式。这是一个非常典型的表达。括号中的部分是lambda的捕获子句,表示它如何与封闭作用域中的局部变量交互。圆括号将包含形参列表,就像函数一样,然后在方括号中是函数定义。

这是一篇不太深奥的好文章。http://www.drdobbs.com/cpp/lambdas-in-c11/240168241

lambda表达式定义了一个匿名函数,该函数可以从其定义的范围内捕获内容。特别是,[&]意味着它通过引用捕获所有自动变量,而()意味着它不接受任何参数。{…}是函数体。有关lambdas的更多信息,请参阅http://en.cppreference.com/w/cpp/language/lambda。

假定Tick期望它的形参是一个可调用对象;lambda可用于此目的,并且易于定义。定义调用操作符的对象也可能在该上下文中工作。函数指针也可以。