![](/img/trans.png)
[英]Error “ no known conversion from 'std::vector<double, std::allocator<double> >' to 'double *' ” when using std::count_if()?
[英]Conversion between 'std::function<double(double)>’ to ‘double (*)(double)’
我试图将自定义lambda传递给需要函数指针的函数(更确切地说是Brent库中的zero
函数)。
我的想法是,我将使用参数创建一次lambda,然后在该函数内部将其评估为多个值x
。
我尝试了该线程中的步骤,但未成功,并且出现no known conversion for argument 4 from 'Function {aka std::function<double(double)>}' to 'double (*)(double)'
错误no known conversion for argument 4 from 'Function {aka std::function<double(double)>}' to 'double (*)(double)'
。 据我了解,编译器不知道如何从这两种类型进行转换。
是否有解决此错误的方法? 如果不必对库进行任何修改,并且可以在我的程序中解决该问题,那就更好了。 这是显示该问题的代码段。
# include <functional>
# include "brent.hpp"
using namespace brent;
typedef std::function<double(double)> Function;
Function function_builder (double a, double b)
{
return [a,b](double x) {
return ( a * x + b );
};
}
int main ( )
{
Function func = function_builder ( 2.0, -1.0 );
double z = zero (0, 1, 0.001, func ); //func should be a function pointer of type double (*)(double)
return 0;
}
在您的情况下,您的lambda函数具有状态-捕获的a,b变量。 无法将有状态的lambda转换为函数的指针,但是...
Brent库不希望指针起作用。 zero
函数声明为:
double zero ( double a, double b, double t, func_base& f )
并具有以下定义的重载:
// This is the overload you asked about, but....
double zero ( double a, double b, double t, double f ( double x ) ){
func_wrapper foo(f);
return zero(a, b, t, foo);
}
但是您应该根据需要使用第一个变体,该变体可以期望:
class func_base{
public:
virtual double operator() (double) = 0;
};
这是个好消息,因为您只需要从func_base派生,然后在其中放一个lambda即可:
template <class Lambda>
class FunctionWithState : public func_base, public Lambda {
public:
FunctionWithState(const Lambda & lambda): Lambda(lambda) {}
double operator()(double x) override
{ return Lambda::operator()(x); }
};
template<class Lambda>
auto function_builder_base (Lambda lambda)
{
return FunctionWithState<decltype(lambda)>(lambda);
}
auto function_builder(double a, double b)
{
return function_builder_base([a,b](double x) {
return ( a * x + b );
});
}
实现细节有些丑陋,但用法合理:
main ( )
{
// func must be "auto" because the type depends on lambda, whose type is unknown.
auto func = function_builder ( 2.0, -1.0 );
double z = zero (0, 1, 0.001, func );
return 0;
}
当然,有可能完全摆脱lambda函数,并管理非模板对象内部的状态。 但是另一方面,从lambda继承可以轻松定义许多其他函数构建器,例如:
auto function_builder3(double a, double b, double c)
{
return function_builder_base([a,b,c](double x) {
return ( a*x*x + b*x + c );
});
}
实际上,您可以在任何地方直接使用function_builder_base
,而无需使用function_builder
中间人。
如果没有将std::function<double(double)>
传递给double(*)(double)
丑陋技巧(例如使用各种全局对象),您将不会很幸运。 关键区别在于,函数指针真正只能仅抽象无状态函数,而带有非空捕获的std::function<double(double)>
或lambda函数则包含状态。
特别是对于布伦特图书馆提到的有 ,然而,一个办法! 该库并没有真正使用函数指针,而是根据func_base
对象传播。 您可以使用简单的适配器获得其中之一:
struct brent_fun: func_base {
std::function<double(double)> fun;
template <typename Fun>
explicit brent_fun(Fun&& fun): fun(std::move(fun)) {}
double operator()(double value) override { return this->fun(value); }
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.