2013-12-09 1 views

답변

23

문제는 C++의 람다 함수가 각 인스턴스에 대해 전달되어야하는 추가 상태 (캡처 된 변수 일명 컨텍스트)를 가질 수 있다는 점입니다 (동일한 람다 함수의 핸들 인스턴스마다 다를 수 있음).

함수는 전달한 핸들에 결합 된 상태를 가질 수 없습니다. 함수 포인터에 이런 상태를 추가하면 괄호 구문 (operator())을 사용하여 호출 할 수있는 래퍼를 작성하게됩니다.

람다 없이 캡쳐를 함수 포인터로 변환 할 수 있다는 사실은 주목할만한 사실입니다. 이는 이 아니기 때문에에 추가 공간이 필요하기 때문에 가능합니다.

+0

나는 유효 기간이 클로저 인스턴스와 동일한 함수 포인터에 * 캡쳐 * 람다 변환을 추가하라는 제안을 읽었습니다. 실제로는 대부분의 아키텍처에서 기계어 명령어와 람다에 대한 포인터를 포함하는 데이터를 작성한 다음이를 실행 가능으로 표시 한 다음 런타임에 방금 작성한 함수에 대한 포인터를 리턴함으로써 가능합니다. 나는 그 제안의 상태가 무엇인지 전혀 모른다. – Yakk

+0

@Yakk 또는 단순히 전역 변수를 사용 하시겠습니까? ;) (사실, 그 이유는 내 대답의 편집에 첫 번째 단락의 마지막 부분을 추가 한 이유입니다.) – leemes

+0

캡처 된 상태가 다른 람다의 여러 인스턴스가 작동하지 않습니다. 기본적으로 많은 플랫폼에서 우리는 그들이 가리키는 코드에 저장된 상태로 함수 포인터를 생성 할 수 있으며'void *, void (* func) (void *)'상태 저장 콜백을 제공하지 않는 수많은 레거시 API가 있습니다 쌍. – Yakk

9

함수에는 상태가 없으므로 lambdas에서 요구하는 기능을 구현할 수 없습니다.

또한 람다가 고유 한 유형을 가지고 있음을 보증합니다.이 람다는 함수만으로는 실제로 할 수 없습니다.

4

이미 언급 한 캡쳐 기능 외에도 성능 또한 이유입니다. 일반적으로 함수 포인터는 인라인 될 수 없습니다. 펑터가 될 수 있습니다. 이것이 std :: sort가 qsort보다 빠릅니다. 앞서 언급했듯이 캡쳐가없는 람다는 함수 포인터로 바뀔 수 있지만 대부분이 오래된 API와 상호 작용합니다. 즉 낡은 win32 API 함수에 람다를 건네 줄 수가 있습니다. 일반적으로 단순한 람다 (lambda)의 경우 컴파일러는 대신 인라인을 선호합니다.

관련 문제