2014-10-29 101 views
2

我正在使用gsl來集成一個函數。該函數構建在一個lambda函數中,該函數具有double和void *作爲輸入,並且輸出double。 現在,如果我使用沒有任何變量捕獲的lambda表達式,一切正常。但是如果我進行可變捕獲,它就不再工作了。lambda函數與gsl的數值積分

任何人都可以解釋我爲什麼這樣嗎?

這裏有兩個代碼片段是我做了解釋我的問題:

這一個正常工作:

int main(int argc, char **argv) 
{ 

    double beg = 0; 
    double end = 10; 

    auto f = [] (double x, void * p) {return 2.0;}; 

    gsl_integration_workspace * w = gsl_integration_workspace_alloc (GSL_INTEGRATION_WORKSPACE_SIZE); 

    double result; 
    double error; 

    gsl_function F; 
    F.function = f; 
    F.params = NULL; 

    gsl_integration_qags (&F, beg, end, 0, GSL_INTEGRATION_RELATIVE_PRECISION, GSL_INTEGRATION_WORKSPACE_SIZE, w, &result, &error); 

    cout<<result<<endl; 

} 

雖然這一個

int main(int argc, char **argv) 
{ 

    double beg = 0; 
    double end = 10; 

    double p = 2.0; 

    auto f = [&] (double x, void * p) {return p;}; 

    gsl_integration_workspace * w = gsl_integration_workspace_alloc (GSL_INTEGRATION_WORKSPACE_SIZE); 

    double result; 
    double error; 

    gsl_function F; 
    F.function = f; 
    F.params = NULL; 

    gsl_integration_qags (&F, beg, end, 0, GSL_INTEGRATION_RELATIVE_PRECISION, GSL_INTEGRATION_WORKSPACE_SIZE, w, &result, &error); 

    cout<<result<<endl; 

} 

上線

產量
F.function = f; 

出現以下錯誤:

Assigning to 'double (*)(double, void *)' from incompatible type '<lambda at /[omissis]/main.cpp>' 

回答

3

@ user657267給出的答案是正確的。這就是爲什麼需要一個小包裝器來將帶捕獲的lambas轉換爲gsl_function。

Here is the wrapper for the f gsl_functionHere is the wrapper for the fdf gsl_function

您可以將lambda函數使用下列方式這兩個答案提出的包裝(我沒有發明了的std ::功能的版本後gsl_function,這是一個衆所周知的答案。我的答案之前我沒有見過的模板版本)。

// std::function version 
double a = 1; 
gsl_function_pp Fp([=](double x)->double{return a*x;}); 
gsl_function *F = static_cast<gsl_function*>(&Fp); 

//template version 
double a = 1; 
auto ptr = [=](double x)->double{return a*x;}; 
gsl_function_pp<decltype(ptr)> Fp(ptr); 
gsl_function *F = static_cast<gsl_function*>(&Fp); 
+0

這正是我一直在尋找的! – 2014-10-30 07:51:41

+0

如果你喜歡,你可以給其他答案:) – 2014-10-30 15:52:34

+0

哪裏是'std :: function'? – Walter 2015-09-27 17:29:17

2

只有沒有捕獲的lambda可以轉換爲函數指針。

[expr.prim.lambda]

6 The closure type for a non-generic lambda-expression with no lambda-capture has a public non-virtual non explicit const conversion function to pointer to function with C++ language linkage (7.5) having the same parameter and return types as the closure type’s function call operator.

本質上這是什麼意思是

[] (double, void*) {return 2.0;}; 

行爲好象它被定義爲

class Lambda 
{ 
public: 
    double operator()(double, void*); 
    operator double(*)(double, void*)() const; 
}; 

如果拉姆達具有但是捕獲的轉換函數沒有定義,並且lambda不能轉換爲常規的函數指針之三。