[英]Pass lambda to numerical library
我正在尝试使用一个数值积分库,要求我向它传递一个double (*f)(double,void*)
作为参数。 如何在相同范围内将其创建的lambda传递给它? 我试过了
auto myLambda = [&](double d, void* data) { ... }
但是lambda的类型无法转换为库所需的类型。 有解决方法吗?
感谢您的时间!
template<class T>using type=T;
template<class F>
struct callback_t {
F data;
void* pdata(){return &data;}
template<class R, class...Args>
operator type<R(*)(Args...,void*)>()const{
return [](Args...args,void*pdata)->R{
F* data=static_cast<F*>(pdata);
return (*f)(std::forward<Args>(args)...);
};
}
};
template<class F>
callback_t<F> callback(F f){
return{std::move(f)};
}
采用:
int scale=3;
auto cb = callback([&](double d){return d*scale;});
然后传递cb
代替函数指针,并cb.pdata()
作为void*
参数。
大概该库还允许您传入data
参数,通过该参数将调用提供的函数。 在这种情况下,您可以定义一个包装程序,将该参数视为指向您要调用的实际对象的指针,并将该调用转发给该对象,也许是这样的:
template <class F>
double function_for_library(double d, void* data) {
F& f = *static_cast<F*>(data);
return f(d);
}
现在,如果您有一些类型为F
任意函数对象f
,则可以像下面这样调用库:
invoke_library(function_for_library<F>, &f); // implicit conversion to void*
对于lambda,您必须使用decltype
但这没什么大不了的。
auto myLambda = /* ... */;
invoke_library(function_for_library<decltype(myLambda)>, &myLambda);
或者,您可以编写另一个推断类型的包装器。
只有没有捕获的lambda可能会衰减到函数指针
我怀疑void*
是传递用户数据的方式。 所以你必须创建一个结构
struct Functor
{
explicit Functor(capture_t&);
void operator()(double d)
{
// Your stuff
}
static void call(double d, void* userdata)
{
(*reinterpret_cast<Functor*>(userdata))(d)
}
private:
capture_t m_capture
};
然后打电话
Functor func(capture);
library_function(&Functor::call, &func);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.