例如,我可以定义一个 lambda 函数:
auto f = [](double value) {double ratio = 100; return value * ratio;}
现在我想生成一个带有比率参数并返回lambda函数的函数,如下所示
auto makeLambda(double ratio) { return [=](double value) {return value * ratio;}; }
如何做到?
例如,我可以定义一个 lambda 函数:
auto f = [](double value) {double ratio = 100; return value * 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);
}
auto func(double x)->decltype(makeLambda(x)){return makeLambda(x);}
- Yakk - Adam Nevraumont@免责声明:这个答案只是在@Slava的回答中添加了额外的论点(但对于评论来说太长了)。
你可能不应该返回lambda表达式,而应该返回函数指针或std::function。
除了效率问题(见下文),API的声明应该告诉你如何使用它。Lambda表达式是一种临时函数 - 设计用于在使用它的地方(局部上下文)有意义。
如果你写了这个:
std::function<double( double )> makeFunction(double ratio);
您的代码将变得更加灵活(不依赖于C++14),定义也更好(您可以查看签名并了解其作用),且具有未来可扩展性(易于理解API背后的意图,从而容易进行扩展而不会破坏客户端代码)。
如果您写成这样:
auto makeFunction(double ratio);
你需要在内联定义它(我猜)。
对于类似MikeSeymour答案的实现,您需要添加一个额外的lambda,以避免编译器的限制。阅读一个返回lambda的lambda实现来确定API返回内容是个大忌。
首先,因为它不明显和晦涩难懂。
其次,它将强加给客户端代码一个需要注释/解释说明才能理解的API,或者强迫客户端阅读实现以知道如何使用它。
如果您无法保证这是一次性代码,则会出现以下情况:
增加WTF / SLOC比率(如果需要阅读实现才能弄清楚返回值,则代码的目的不清楚)
有些不明显的东西,您将不得不为整个项目维护。 这称为杂物,这就是使糟糕的旧代码成为糟糕的旧代码的原因。
如果您需要返回functor,最好返回std::function
;返回类型几乎大喊“返回functor”。
如果这对您的需求效率太低,可以稍后进行优化/特殊化 - 例如,通过返回struct X { double operator()(double); }
实例。
关于能够保证这不是生产代码的说明:
我见过很多情况,例如:
我正在查看三年前的可怕代码,人们告诉我最初这是原型,但我们向客户展示了应用程序,他们要求“按原样”使用它,现在客户端依赖它,但我们没有时间预算来清理它。
我将丑陋的原型代码发送给其他人(例如“我们可以做一些遵循此算法的东西”),然后在源代码控制中看到它作为解决方案被提交。
人们编写hack覆盖hack,因为代码已经很糟糕,再加一个hack无所谓(这其实是一个非常常见的借口)。
std::function<double( double )>
类型。调用它可能会增加额外的函数调用成本,在大多数情况下这是微不足道的。std::function
使用了一种称为“类型擦除”的技术,这会导致每次调用都产生一次间接调用(通常实现为虚函数)。 - Simple