All Articles

C++

[C++] 갈무리 모드(Capture mode)

Effective Modern C++를 읽다 챕터 31. "기본 갈무리 모드를 피하라"는 내용을 보게되었다.

갈무리 모드(캡쳐 모드)는 람다식에서 쓰이는 아래와 같은 형태에서

 

[=] (int x) { return x; }

 

[=] 와 같은 변수를 넘겨주는 형식을 의미한다.

여기서 = 는 this 포인터를 넘겨주는 것을 의미하며 아래 MSDN에서 자세한 사항을 확인할 수 있다.

docs.microsoft.com/ko-kr/cpp/cpp/lambda-expressions-in-cpp?view=msvc-160

 

 

Effective Modern C++의 챕터 31에서 설명하는 기본 갈무리 모드는 아래와 같은 형태로 람다식을 사용하는 것을 피하라는 의미를 전한다.

 

[&<지역변수>] // 참조(by_reference)
[&] // 지역 변수에 대한 암시적 참조
[=] // this 포인터를 통한 멤버 변수에 대한 암시적 참조

 

지역변수의 값을 값에 의한(by_value) 복사를 통해 캡쳐하는 것이 아니라 참조를 하게되면 참조 대상을 잃을 수 있다는 것인데 this 포인터 또한 잃을 수 있으니 조심하라는 것이다.

 

 

auto <새변수> = <멤버변수 혹은 지역변수>
[<새변수>] // 값에 의한(by_value)
// 혹은
[<새변수> = <멤버변수>] // =(this 포인터)를 통한 복사

 

위와 같은 형태로 복사해서 사용하도록 권장한다.

 

위 내용은 챕터 31을 이해한 것을 매우 축약함.

 


근데 참조가 아니라 복사를 이용함으로써 일어나는 손해를 줄이고 싶어졌다. 위 책의 챕터 32에서는 이동 초기화를 통해 복사를 이용함으로써 일어나는 손해를 이동 연산으로 해결한다.

 

std::vector<double> data;

// C++11
auto func = std::bind( [](std::vector<double>& data) mutable { ... },
                       std::move(data));
// C++14
auto func = [data = std::move(data)] { ... };

위의 갈무리 모드(캡쳐절)에 이동 초기화로 새 변수(정확한 표현은 클로저 클래스의 자료맴버)이고 새로운 갈무리 매커니즘은 초기화 갈무리(init capture)이라고 한다.

 

 

갈무리라는 용어를 찾아봐도 Effective Modern C++에서 밖에 사용안하는 것 같은데 캡처라는 용어가 좀더 직관적이고 찾기도 쉬우니 캡처라는 용어를 사용해야겠다.