为什么隐含的“lambda to function pointer conversion”禁止静态成员的“by reference”捕获?

时间:2012-07-17 22:55:47

标签: c++ lambda c++11

C ++ 11标准说(或者至少是我拥有的版本 - 而不是最终版本):

  

具有无lambda-capture 的lambda表达式的闭包类型具有   public非虚拟非显式const转换函数指针   具有与闭包相同的参数和返回类型的函数   type的函数调用操作符。

我理解为什么不能从有状态lambda获取函数指针,因为函数指针本身不能保存任何数据。

但是当捕获的对象只是静态成员/静态变量时,没有这样的限制,因为对捕获的对象的引用可以在函数本身中进行硬连线。

struct A {
    static int count = 0;
    void foo() {
         static int bar = 0;
         auto fun = [&]()->void {
             count++;
             bar++;
         };
         void(*ptrFun)();
         ptrFun = fun; // forbidden by the quoted wording
    }
};

为什么不能始终将lambda转换为函数指针,只要前者是无状态的?我错过了什么或者委员会忘记了这一点吗?

1 个答案:

答案 0 :(得分:9)

A::count根本不需要被捕获。只需要捕获this和局部变量。具有静态存储持续时间的变量(例如,静态数据成员,命名空间范围变量或函数本地静态变量)不需要被捕获,因为它们是“唯一的”。每个这样的变量只有一个实例,因此不需要捕获对象的引用。

如果从lambda中删除默认捕获(即,将[&]更改为[])并定义count,则应该编译时没有错误。 (我已经验证了Visual C ++ 2012 RC和g ++ 4.5.1都接受了代码;我必须做的唯一更改是移动count的内联初始化,因为这些编译器都不支持C ++ 11功能。)