2014-10-29 3 views
2

나는 함수를 통합하기 위해 gsl로 작업 중이다. 이 함수는 double과 void *를 입력으로 가지며 출력으로 double을 갖는 람다 함수로 만들어졌습니다. 변수 캡처없이 람다를 사용하면 모든 것이 잘 작동합니다. 그러나 변수 캡처를 수행하면 더 이상 작동하지 않습니다.람다 함수와 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

, 그것은 잘 알려져 당신은 (내가 표준 : 기능 버전을 발명하지 않은 다음과 같은 방법으로이 두 가지 답변에서 제안 된 래퍼를 사용 후 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

이것은 내가 찾고있는 것입니다. –

+0

마음에 드시면 다른 답변에 투표 할 수 있습니다 :) –

+0

여기서'std :: function'은 어디에 있습니까? – Walter

2

캡처되지 않은 람다 만 함수 포인터로 변환 할 수 있습니다.

는 [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; 
}; 

정의 것처럼이다 그러나 변환 함수는 정의되어 있지 않으며 람다는 일반 함수 poin으로 변환 될 수 없습니다 ter.

관련 문제