C++11下面的lambda函数作用域是什么?

3
关于lambda函数的一个简单问题。我发现在使用gcc编译器时,如果lambda没有捕获,那么operator()函数会被隐式转换为函数指针。因此,看下面这个简化的例子,我应该期望这个函数的生命周期在回调中是可用的吗?lambda函数在哪个作用域定义?局部作用域、包作用域还是全局作用域?如果在函数退出后调用lambda函数会有什么问题吗?我不想在这里使用std::function,请不要用std::function返回值来解决问题。我的问题只是想了解该函数(没有捕获)的作用域,并且它是否在程序的整个生命周期内都可用。
#include <iostream>
typedef int(*fPtrT)(int,int);     

 fPtrT fx() { 
    return static_cast<fPtrT>([](int i, int j){return i+j;});
 }

int main()
{
    std::cout << fx()(5,2) << std::endl;
}

你的 fx() 函数创建了一个 r-value 变量,其作用域在 main() 函数执行期间一直存在。 - Colin Basnett
@cmbasnett 谢谢,但我已经知道那些了。我想问的是,编译器创建 lambda 对象本身的作用域是什么。 - bjackfly
2个回答

8
一个lambda表达式返回一个匿名定义的类的实例(类型只有编译器知道)。这个类重载了operator()以充当function object
此外,不闭合任何状态的lambda表达式还具有以下规范:它们可以隐式转换为C风格的函数指针。在这些情况下,想象一下operator()只调用一个静态函数(隐式转换是指向该静态函数的指针)。
了解所有这些,我们可以说关于你发布的代码以下几点:
  • 每次调用fx函数时,都会创建一个匿名类的实例
    • 这个实例是一个r-value;因此,它只存在于语句结束之前
  • fx函数返回的函数指针实际上是指向静态函数的指针
  • 拥有该函数指针的人可以安全地使用它(因为它是一个没有共享状态的静态函数)

1
+1 这个语句有助于理解:“在这些情况下,可以想象操作符()只是调用一个静态函数(而隐式转换是指向该静态函数的指针)。” - bjackfly

3

一个不捕获任何内容的lambda表达式可以在任何地方安全使用。

如果它通过引用捕获,则仅在其引用的对象的生命周期内才安全。

如果它通过值捕获,则在任何地方都是安全的——它只是一个对象。


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