如何返回一个lambda函数

How to return a lambda function?

本文关键字:一个 lambda 函数 返回 何返回      更新时间:2023-10-16

例如,我可以将lambda函数定义为

auto f = [](double value) {double ratio = 100; return value * ratio;}

现在我想用ratio作为参数生成一个函数并返回lambda函数,如

auto makeLambda(double ratio) { return [=](double value) {return value * ratio;}; }

怎么做?

使用c++ 14函数返回类型推导,应该可以工作。

在c++ 11中,您可以定义另一个lambda(它可以推断返回类型),而不是函数(它不能):

auto makeLambda = [](double ratio) {
    return [=](double value) {return value * ratio;};
};

如注释中所述,如果您特别想要一个函数,可以进一步包装:

auto makeLambdaFn(double ratio) -> decltype(makeLambda(ratio)) {
    return makeLambda(ratio);
}

@免责声明:这个答案只是给@Slava的答案添加了额外的参数(但是对于注释来说太长了)。

您可能不应该返回lambda,而应该返回函数指针或std::函数。

除了效率问题(见下文),API的声明应该告诉你如何使用它。lambda是一个临时函数——在你使用它的地方(在本地上下文中),它是有意义的。

如果你这样写:

std::function<double( double )> makeFunction(double ratio);

你的代码将更加灵活(不依赖于c++ 14),更好的定义(你可以查看签名并知道它在做什么)和面向未来(很容易理解API背后的意图,这使得以后很容易扩展而不会搞砸客户端代码)。

如果你这样写:

auto makeFunction(double ratio);

你必须定义它内联(我猜)。

对于类似MikeSeymour回答的实现,您需要添加一个额外的lambda,以避免编译器的限制。阅读一个lambda返回一个lambda的实现,只是为了弄清楚API返回的是什么,这是一个大禁忌。

首先,因为它不明显且晦涩。

第二,它会强加给客户端代码,一个API,要么需要一个注释/解释性说明来理解,要么强制客户端阅读它的实现来知道如何使用它。

如果你不能保证是一次性代码,你将:

  • 增加代码的WTF/SLOC比率(代码的目的不明确,如果你需要阅读实现来弄清楚它返回什么)

  • 有一些不明显的东西,你必须在整个项目中维护。这被称为cruft,这就是为什么糟糕的遗留代码糟糕的遗留代码)。

如果你需要返回一个函子,你最好返回一个std::function;返回类型实际上是"返回一个函子"。

如果这对于您的需求来说效率太低,您可以稍后对其进行优化(特殊化)——例如,通过返回一个struct X { double operator()(double); }实例。

关于能够保证这不是生产代码的注意事项:

我见过很多这样的情况:

  • 我看着可怕的三年前的代码,人们告诉我最初这是原型,但我们向客户展示了应用程序,他们要求它"原样",现在客户依赖它,但我们没有时间预算来清理它

  • 我将丑陋的原型代码发送给其他人(就像"我们可以按照这个算法做一些事情"),并看到它作为源代码控制的解决方案提交。

  • 人们不断地修改代码,因为代码已经很容易修改了,再修改一次也没关系(这实际上是一个很常见的借口)。

可以返回std::function<double( double )>。调用它可能需要额外的函数调用成本,在大多数情况下,这是微不足道的。