2013-06-28 2 views
5

나는 람다에 '참조'를 캡처하려면, 난 함수 포인터가 같이 트릭을 할 것이라고 생각 :람다에 대한 '참조'는 어떻게 만듭니 까?

int (*factorial)(int) = [&](int x){ 
    return (x < 2) 
     ? 1 
     : x * factorial(x - 1); 
}; 

하지만 난 cannot convert from main::lambda<......> to int(_cdecl *)(int)를 얻을.

그러면 람다를 가리키는 적절한 방법은 무엇입니까?

+3

람다는 아무것도 포착하지 않으면 함수 포인터로 변환 될 수 있습니다. – jrok

+0

쿨, 네 말이 맞아. 알았어, 고마워. – sircodesalot

+0

이것은 거의 http://stackoverflow.com/questions/2067988/recestive-lambda-functions-in-c0x – doctorlove

답변

6

람다는 상태 비 저장이 아니므로 함수 포인터로 변환 할 수 없습니다. 대신 std::function을 사용하십시오.

std::function<int(int)> factorial = [&](int x){ 
    return (x < 2) 
     ? 1 
     : x * factorial(x - 1); 
}; 
+1

"원시"람다와 비교할 때 경고 메시지로 드는 간접비가 있습니다. 각각의 호출은 대략'virtual' 메소드를 호출하는 것과 같습니다. 그렇게 나쁘지는 않지만 호출에서 수행되는 작업과 비교할 때 중요합니다. – Yakk

+0

@Yakk 네,'std :: function'의 타입 삭제 비용을 지불해야합니다; 몇 주 전부터 그 대답을 찾고있었습니다 :) – Praetorian

+0

'무국적자가 아니라는 것'은 무엇을 의미합니까? 또한 @Yakk는 간접비가 무엇입니까? – sircodesalot

5

이것은 당신이 이미 가지고있는 가장 가까운 것 :

std::function<int (int)> factorial = [&](int x){ 
    return (x < 2) 
     ? 1 
     : x * factorial(x - 1); 
}; 

는 일반적으로 당신은 또한 auto를 사용할 수 있지만 함수가 재귀 때문에이 경우에는 작동하지 않습니다.

+1

의'auto' 코드와 중복됩니다. 링크 된 질문을 참조하십시오. –

+0

@JesseGood : 좋은 지적입니다 - 고마워요. –

5

이미 좋은 답변이 있습니다. 다음은 단지 호기심에 불과하지만 사용을 제안하지는 않습니다.

다른 사람들이 대답했듯이 람다 factorial은 자체를 캡처하려고 시도하므로 상태가 아닙니다. 따라서 함수 포인터로 변환 할 수 없습니다.

주면서 전역 또는 static 물체를 포착 할 필요가 없습니다, 그래서 당신은 다음 factorial 전역 또는 static 변수를 만들 경우 당신은 그것을 캡처 할 필요가 없습니다이 잘 (GCC 4.7.2)

#include <iostream> 

    typedef int (*function)(int); 

    int main() { 
     static function factorial = [](int x){ 
      return (x < 2) ? 1 : x * factorial(x - 1); 
     }; 
     std::cout << factorial(5) << '\n'; 
    } 
를 작동

#include <iostream> 

    typedef int (*function)(int); 

    function make_factorial() { 
     static function factorial = [](int x){ 
      return (x < 2) ? 1 : x * factorial(x - 1); 
     }; 
     return factorial; 
    } 

    int main() { 
     auto factorial = make_factorial(); 
     std::cout << factorial(5) << '\n'; 
    } 

그런 다음 typedef 제거 더 :-)를 당황하게하려면 :

당신은 또한이 같은 공장을 만들 수 있습니다3210

// This is a function returning a pointer to a function taking an int and returning an int. 
    int (*(make_factorial)())(int) { 
     static int (*factorial)(int) = [](int x){ 
      return (x < 2) ? 1 : x * factorial(x - 1); 
     }; 
     return factorial; 
    } 
관련 문제