【问题标题】:How do I create a 'reference' to a lambda?如何创建对 lambda 的“引用”?
【发布时间】:2013-06-26 07:26:04
【问题描述】:

我想捕获对 lambda 的“引用”,我认为函数指针可以解决问题,如下所示:

int (*factorial)(int) = [&](int x){
    return (x < 2)
        ? 1
        : x * factorial(x - 1);
};

但我得到cannot convert from main::lambda&lt;......&gt; to int(_cdecl *)(int)

那么指向 lambda 的正确方法是什么?

【问题讨论】:

  • 如果 lambda 没有捕获任何内容,则可以将其转换为函数指针。
  • 酷,你是对的。很高兴知道,谢谢。
  • 这几乎是stackoverflow.com/questions/2067988/…的复制品

标签: c++ c++11 lambda


【解决方案1】:

由于 lambda 不是无状态的,它不能转换为函数指针。请改用std::function

std::function<int(int)> factorial  = [&](int x){
  return (x < 2)
      ? 1
      : x * factorial(x - 1);
};

【讨论】:

  • 与“原始” lambdas 相比,这具有不小的间接成本,作为警告。每次调用大致相当于调用一个virtual 方法。这还不错,但与通话中所做的工作相比,意义重大。
  • @Yakk 是的,你需要支付std::function 类型擦除的费用;我只是在寻找几周前的答案以链接到:)
  • not stateless 是什么意思?另外,@Yakk 的间接费用是多少?
  • @sircodesalot 有状态 lambda 是捕获状态的 lambda。即,如果您在 lambda 开头的 [] 中有任何内容,则您的 lambda 具有状态。我使用有关间接费用的信息编辑了我的答案。
  • @Praetorian:我猜你在找this one
【解决方案2】:

这将最接近您已经拥有的:

std::function<int (int)> factorial = [&](int x){
    return (x < 2)
        ? 1
        : x * factorial(x - 1);
};

通常你也可以使用auto,但在这种情况下它不起作用,因为函数是递归的。

【讨论】:

    【解决方案3】:

    你已经有了很好的答案。以下只是一个好奇心,但我不建议您使用它。

    正如其他人的回答所说,lambda factorial 试图捕获自己,因此它不是无状态的。因此,它不能转换为函数指针。

    Lambdas 不需要捕获全局或 static 对象,因此如果您将 factorial 设为全局或 static 变量,那么您不需要捕获它并且这工作正常(gcc 4.7.2)

        #include <iostream>
    
        typedef int (*function)(int);
    
        int main() {
            static function factorial = [](int x){
                return (x < 2) ? 1 : x * factorial(x - 1);
            };
            std::cout << factorial(5) << '\n';
        }
    

    你也可以像这样创建工厂:

        #include <iostream>
    
        typedef int (*function)(int);
    
        function make_factorial() {
            static function factorial = [](int x){
                return (x < 2) ? 1 : x * factorial(x - 1);
            };
            return factorial;
        }
    
        int main() {
            auto factorial = make_factorial();
            std::cout << factorial(5) << '\n';
        }
    

    如果您想进一步混淆 :-) 然后消除 typedef:

        // This is a function returning a pointer to a function taking an int and returning an int.
        int (*(make_factorial)())(int) {
            static int (*factorial)(int) = [](int x){
                return (x < 2) ? 1 : x * factorial(x - 1);
            };
            return factorial;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-16
      • 1970-01-01
      • 2017-05-10
      • 1970-01-01
      • 2016-06-04
      • 1970-01-01
      • 2020-06-18
      • 1970-01-01
      相关资源
      最近更新 更多