미분류

C++에서 Lambda Expression의 Capture를 받을 수 있는 함수포인터 사용하기

C++의 기존 방식의 함수포인터로는 람다 표현식의 Capture를 받을 수 없다. Capture란 람다 표현식을 정의한 함수의 변수 등을 사용할 수 있게 해주는 장치이다.

아래와 같은 식은 C++ 컴파일러에서 오류를 일으킨다.

typedef void ( *EXAMPLE ) ();
int main ( void )
{
	int a = 10, b = 20;
	EXAMPLE example = [ & ] () { printf ( "a = %d, b = %d\n", a, b ); };
	example ();

	return 0;
}

이 코드를 컴파일하면 아래와 같은 오류가 발생한다.

C2440 ‘초기화 중’: ‘main::’에서 ‘EXAMPLE'(으)로 변환할 수 없습니다.

이 오류를 해결할 수 있는 방법은 두 가지가 있다. 다만 한 방법은 함수의 매개변수로 넘길 수 있는 함수포인터 데이터 타입을 구성할 수 없다.

1. auto 타입 사용하기

C++ 11에서 추가된 auto 자료형을 사용하면 람다 표현식에 Capture를 넘길 수 있다.

int main ( void )
{
	int a = 10, b = 20;
	auto example = [ & ] () { printf ( "a = %d, b = %d\n", a, b ); };
	example ();

	return 0;
}

이 방법을 사용하면 사용할 함수의 함수포인터 데이터 타입을 정의할 수 없어서 함수의 매개변수에서는 람다 표현식을 받을 수 없다는 단점이 있다.

2. std::function 템플릿 사용하기

마찬가지로 C++ 11에서 추가된 STL인 std::function 템플릿 클래스를 사용하면 람다 표현식에 Capture를 넘길 수 있다. std::function 템플릿 클래스는 functional 헤더파일에 있다.

#include <functional>
typedef std::function EXAMPLE;
int main ( void )
{
	int a = 10, b = 20;
	EXAMPLE example = [ & ] () { printf ( "a = %d, b = %d\n", a, b ); };
	example ();

	return 0;
}