所以我正在尝试编写一个与c ++ 11 lambdas一起使用的Integration函数.代码看起来像这样:
double Integrate(std::function<double(double,void*)> func, double a,double b,std::vector<double> & params)
{
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);
gsl_function F;
F.function =func;
F.params = (void*)¶ms;
double error,result;
gsl_integration_qag (&F, a, b, 0, 1e-7, 1000,GSL_INTEG_GAUSS61,w, &result, &error);
gsl_integration_workspace_free (w);
return result;
}
void Another_function()
{
//...
Integrate([](double a,void* param)
{
return ((vector<double> *)params)->at(0)*a+((vector<double> *)params)->at(1);
}
,0,3,{2,3});
}
Run Code Online (Sandbox Code Playgroud)
试图编译它,编译器说:
error: cannot convert ‘std::function<double(double, void*)>’ to ‘double (*)(double, void*)’ in assignment
Run Code Online (Sandbox Code Playgroud)
关于线
F.function =func;
Run Code Online (Sandbox Code Playgroud)
但如果我写:
F.function =[](double a,void* param)
{
return ((std::vector<double> …Run Code Online (Sandbox Code Playgroud) 在此std :: function vs template链接中,对std :: function的开销进行了很好的讨论。基本上,为避免传递给std :: function构造函数的函子的堆分配导致10倍的开销,必须使用std :: ref或std :: cref。
来自@CassioNeri答案的示例显示了如何通过引用将lambdas传递给std :: function。
float foo(std::function<float(float)> f) { return -1.0f * f(3.3f) + 666.0f; }
foo(std::cref([a,b,c](float arg){ return arg * 0.5f; }));
Run Code Online (Sandbox Code Playgroud)
现在,英特尔线程构建模块库使您能够使用lambda / functor并行评估循环,如下例所示。
示例代码:
#include "tbb/task_scheduler_init.h"
#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include "tbb/tbb_thread.h"
#include <vector>
int main() {
tbb::task_scheduler_init init(tbb::tbb_thread::hardware_concurrency());
std::vector<double> a(1000);
std::vector<double> c(1000);
std::vector<double> b(1000);
std::fill(b.begin(), b.end(), 1);
std::fill(c.begin(), c.end(), 1);
auto f = [&](const tbb::blocked_range<size_t>& r) {
for(size_t j=r.begin(); j!=r.end(); ++j) …Run Code Online (Sandbox Code Playgroud) 我有以下功能
static void p (){
}
Run Code Online (Sandbox Code Playgroud)
我想将指向 p 的函数指针传递给函数 x。
void x(void * ptr){
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试以下操作,但它不起作用。
...
x(ptr);
Run Code Online (Sandbox Code Playgroud)
注意 x 和 p 属于不同的类。我收到以下编译错误。
invalid conversion from 'void (*)()' to 'void*' [-fpermissive]
Run Code Online (Sandbox Code Playgroud) 我想迭代一个整数的所有可能值。此代码不起作用,因为终止条件永远不会变为假:
for (uint32_t i = 0; i <= 0xFFFFFFFF; i++)
std::cout << i << std::endl;
Run Code Online (Sandbox Code Playgroud)
我想出了这个:
auto loopBody = [](uint32_t value)
{
std::cout << value << std::endl;
};
uint32_t last = 0xFFFFFFFF;
for (uint32_t i = 0; i < last; i++)
loopBody(i);
loopBody(last);
Run Code Online (Sandbox Code Playgroud)
不过,它相当丑陋。有没有更漂亮的方法来做到这一点?
我的代码看起来像这样:
template<typename F>
void printHello(F f)
{
f("Hello!");
}
int main() {
std::string buf;
printHello([&buf](const char*msg) { buf += msg; });
printHello([&buf]() { });
}
Run Code Online (Sandbox Code Playgroud)
问题是 - 如何限制F类型只接受具有签名的lambda void(const char*),以便第二次调用printHello不会在内部某个不明显的位置失败,printHello而是在调用printHello错误的行上失败?
== ==编辑
我知道是std::function在这种特殊情况下(是什么,如果我真的想打印"你好"我会使用),解决它.但std::function实际上是其他的东西并且需要付出代价(无论成本如何都很小,截至2016年4月,GCC和MSVC 无法优化虚拟呼叫).所以我的问题可以看作是纯粹的学术问题 - 是否有"模板"方法来解决它?