"std::function<double(double)>"到"double (*)(double)"之间的转换
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)’
错误。据我了解,编译器不知道如何从这两种类型进行转换。
是否有解决此错误的方法?如果不必对库进行任何修改,并且可以在我的程序中解决,那就更好了。下面是显示问题的一段代码。
# 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 转换为指向函数的指针,但是......
布伦特库不需要指向函数的指针。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); }
};
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- 在cuda线程之间共享大量常量数据
- 在c代码之间共享数据的最佳方式
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- (double) 和 double() 之间的区别
- "+=" 操作在类型之间不起作用 std::复杂<double>和__complex__双精度
- "std::function<double(double)>"到"double (*)(double)"之间的转换
- 使用 double 在 C++ 中初始化 int 之间的差异
- C++:快速/并行计算两个"std::vector<double>"向量之间的L1距离
- 无法使用<double> QTcpSocket 和 QDataStream 在服务器和客户端之间传输 QVector
- 一个关于C++中double和int之间转换的奇怪结果
- 在 int 和 double 之间进行转换有多贵
- istream的运算符之间的差异>>libc++和libstdc++之间的double&val)
- 在C++中,<double>static_cast(a)和双(a)之间有什么区别?
- C中double**和double(*)[2]之间的差异
- 在这个输入中,float和double之间的区别是什么
- c-string和(int,double,float)之间的动态分配
- 为什么我在double和c++之间的比较失败
- 有没有一种类型可以在Float和Double之间切换