如何返回一个lambda函数
How to return a lambda function?
例如,我可以将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 )>
。调用它可能需要额外的函数调用成本,在大多数情况下,这是微不足道的。
- 如何将 lambda 函数作为参数发送到另一个函数
- C++ 一个lambda浅拷贝const Type&如果它被赋予一个命名捕获,如[copy=val](){}?
- 创建一个带有 lambda 的 std::函数,而不知道函数的参数
- 如何参数化用作另一个 lambda 参数的 lambda
- 是否可以将带有捕获和参数的 lambda 传递给另一个函数?如果是这样,如何?
- C++:实现一个接收lambda作为输入的高阶函数
- 带有自定义deleter的std::unique_ptr对象的大小(一个由ref捕获的lambda)
- c++:为什么一个特定的参数必须由lambda中的值捕获
- 在另一个 lambda 中捕获一个 lambda 可能会违反 const 限定符
- 如何从另一个lambda函数调用lambda函数
- 通过捕获作为另一个lambda的参数将lambda传递
- 将函数参数传递给另一个lambda
- 在另一个lambda中调用catch块中捕获的lambda会产生GCC错误
- 将指向lambda函数的指针赋值给指向另一个lambda函数的指针
- 如何返回一个lambda函数
- c++ 11变量捕获与lambda内部的另一个lambda
- 给定一个lambda捕获,哪些规则决定结果闭包成员的类型
- 我如何创建一个lambda函数来匹配boost::函数参数,而不使用c++ 0x
- Boost Lambda/Phoenix-如何处理返回另一个Lambda的Lambda
- 我可以有主窗口过程作为一个lambda在WinMain