感谢C++ 11,我们收到了std::functionfunctor包装器系列.不幸的是,我一直只听到关于这些新增内容的不好的事情.最受欢迎的是它们非常慢.我对它进行了测试,与模板相比,它们真的很糟糕.
#include <iostream>
#include <functional>
#include <string>
#include <chrono>
template <typename F>
float calc1(F f) { return -1.0f * f(3.3f) + 666.0f; }
float calc2(std::function<float(float)> f) { return -1.0f * f(3.3f) + 666.0f; }
int main() {
using namespace std::chrono;
const auto tp1 = system_clock::now();
for (int i = 0; i < 1e8; ++i) {
calc1([](float arg){ return arg * 0.5f; });
}
const auto tp2 = high_resolution_clock::now();
const auto d = duration_cast<milliseconds>(tp2 - tp1);
std::cout << …Run Code Online (Sandbox Code Playgroud) 不仅仅是一般情况,我有一个非常具体的例子:在GSL(GNU科学库)中,使用的主要函数类型(为了执行集成,根查找,...)是gsl_function,它有一个属性function类型是 double(*)(double, void *)
说我想创建一个gsl_function从double a_squared(double a) {return a*a};.我a__squared的类型是double(*)(double)我想创建一个convert函数接受参数(double(*)(double) f)并返回一个double(*)(double, void *)满足的类型的对象convert(f)(double a, NULL) == f(a)
但经过一些研究,似乎我无法在我的convert函数中定义另一个函数.如何进行 ?
我只是尝试在 C++ 中集成一个函数。我一直在尝试使用 gsl,因为我在网上看到了这个推荐。我遵循了 gsl 示例,但收效甚微。
这是我的 C++ 代码:
double inverseE(double z){
double inverseE = 1.0/(std::sqrt(Om0*std::pow(1.0+z,3.0)+1.0-Om0));
return inverseE;
}
double comoving_distance(double z){
gsl_integration_workspace * w
= gsl_integration_workspace_alloc (1000);
double result, error;
gsl_function iE;
iE.function = &inverseE;
gsl_integration_qags (&iE, 0, z, 0, 1e-7, 1000,
w, &result, &error);
gsl_integration_workspace_free (w);
cout << result << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为了澄清起见,Python 中的相同代码(有效)如下所示:
def iE(z):
return 1/(np.sqrt(Om0*np.power(1+z,3)+1-Om0))
def comoving_distance(z):
return (c/H0)*quad(iE,0,z)[0]
Run Code Online (Sandbox Code Playgroud)
quad 执行集成的地方(它是一个 scipy 模块)。
我收到两条错误消息:
ISO C++ 禁止将未限定的或带括号的非静态成员函数的地址作为指向成员函数的指针。说 '&cosmo::inverseE' [-fpermissive]
不能在赋值中将'double (cosmo:: …