2 분 소요

개요

  • [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