[C++] lambda, capture by value 주의사항

capture by value 가 lambda 식에 언급된 외부 변수의 값을 무조건 복사한다고 생각하면, 잘못된 코드를 만들 수 있다. 아래 코드와 같이 m_value 에 대해 capture by value 를 했다고 생각하지만

class BadClosureMaker
{
public:
	BadClosureMaker() : m_value(2012) {}

	std::function<int (void)> CreateClosure()
	{
		auto f = [=](void)
		{
			return m_value;
		};
		return f;
	}

private:
	int m_value;
};

실제로는 m_value를 capture 한 것이 아니라 BadClosureMaker 의 this 를 capture 한다. 만약 CreateClosure 에 의해 생성된 closure가 사용되기 전에 BadClosureMaker 가 delete 된다면, 잘못된 값에 접근한다.

[C++] Lambda의 Recursive

lambda 는 자체적으로 recursive 를 사용할 수 없다. overview of the new C++1, slide 80 에서 다음과 같은 구현을 제시한다.

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

한 가지 주의할 점이 있다. factorial object 를 다른 std::function<> object 로 복사 한 후에 factorial object 가 파괴되면 bad_function_call 에러가 발생한다.

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

cout<<f(4)<<endl; //bad_function_call!! 
  1. http://www.artima.com/shop/overview_of_the_new_cpp