Updated:

2 minute read

개요

  • [capture](parameters){body}
  • 캡쳐
    • []
      • 캡쳐하지 않음
    • [&]
      • 모든 변수에 대해 암시적으로 레퍼런스 캡쳐
    • [=]
      • 모든 변수에 대해 암시적으로 복사 캡쳐
      • 현재 객체(this)는 참조로 캡쳐(before C++20)
      • read only이며 수정이 필요한 경우 mutable 키워드 이용
    • [a, &b]
      • a 변수는 복사, b 변수는 레퍼런스 캡쳐
  • C++17
    • constexpr를 지정하지 않아도 constexpr로 동작
  • C++20
    • 템플릿 지원
    • 템플릿 인자에 람다 전달 가능
    • consteval 지정 가능
      • consteval와 constexpr는 동시 지정 불가능
    • 캡쳐 기본값이 =인 경우 this의 암시적 캡쳐를 권장하지 않음
      • *this(after C++17) 혹은 this(after C++20)으로 명시적 캡쳐 필요


예제

  • C++11
    • 코드
         #include <iostream>
         #include <string>
              
         using namespace std;
              
         int main() {
         	auto f1 = []() { cout << "f1 call" << endl; };
         	f1();
              
         	cout << "------" << endl;
              
         	int i = 0;
         	auto f2 = [=]() { cout << "f2 call : " << i << endl; };
         	f2();
         	cout << "i = " << i << endl;
              
         	cout << "------" << endl;
              
         	i = 0;
         	auto f3 = [&](int add) { i += add; };
         	f3(1);
         	cout << "i = " << i << endl;
              
         	cout << "------" << endl;
              
         	i = 0;
         	string s = "a";
         	auto f4 = [i, &s]() { s += to_string(i); };
         	f4();
         	cout << "s = " << s << endl;
              
         	cout << "------" << endl;
              
         	auto f5 = []() { return "f5 call"; };
         	cout << f5() << endl;
              
         	cout << "------" << endl;
              
         	i = 1;
         	[i]() mutable {
         		cout << i << endl;
         		i = 2;
         		cout << i << endl;
         	}();
              
         	return 0;
         }
      
    • 실행 결과
         f1 call
         ------
         f2 call : 0
         i = 0
         ------
         i = 1
         ------
         s = a0
         ------
         f5 call
         ------
         1
         2
      
  • C++20
    • 코드
         #include <iostream>
              
         using namespace std;
              
         template <typename T> void func1(int i) {
         	T t;
         	t(i);
         }
              
         class Test {
         	private:
         		int i = 1;
              
         	public:
         		void Func() {
         			[=]() { cout << this->i << endl; }();
         			[=, this]() { cout << this->i << endl; }();
         			[&]() { cout << this->i << endl; }();
         		}
         };
              
         int main() {
         	func1<decltype([](int i) { cout << i << endl; })>(1);
              
         	cout << "------" << endl;
              
         	auto func2 = []<typename T>(T a) { cout << a << endl; };
         	func2(1);
         	func2("a");
              
         	cout << "------" << endl;
              
         	Test().Func();
              
         	return 0;
         }
      
    • 실행 결과
         main.cpp: In lambda function:
         main.cpp:16:25: warning: implicit capture of ‘this’ via ‘[=]’ is deprecated in C++20 [-Wdeprecated]
            16 |                         [=]() { cout << this->i << endl; }();
               |                         ^
         main.cpp:16:25: note: add explicit ‘this’ or ‘*this’ capture
         1
         ------
         1
         a
         ------
         1
         1
         1