상세 컨텐츠

본문 제목

[C++11] Lamda Expressions

C++/Modern C++(11, 14, 17, 20)

by deulee 2023. 8. 26. 17:42

본문

`lamda`는 C+11부터 도입된 기능으로, 이름 없는 함수 객체로 지역내에 있는 변수들을 캡처하는 기능이 있다.

 

우선 `lamda`의 구조는 다음과 같다.

[capture](parameters) -> return_type {
	// 함수 몸체
} (call lamda); // 생략 가능

 

각각의 요소는 다음과 같다.

  • `capture`는 외부 변수를 람다 내부에서 사용할 때 그 값을 어떻게 캡처할 것인지를 지정함.
  • `parameters`는 람다 함수의 매개변수를 정의함.
  • `return_type`은 람다 함수의 반환 타입을 지정함. (생략 가능)
  • `함수 몸체`는 실제 함수의 내용을 작성하는 부분
  • `호출 인자`는 함수 호출 시 인자를 의미함. (생략 가능)

 

캡처를 할 때 다양한 특징이 있는데 다음과 같다.

  • `[]` - 아무것도 캡처하지 않음.
  • `[=]` - 지역내의 모든 객체 (지역 변수, 매개 변수)의 값을 복사함.
  • `[&]` - 지역내의 모든 객체 (지역 변수, 매개 변수)의 값을 참조함
  • `[this]` - `this`를 참조함
  • `[a, &b]` - `a`의 값을 복사하고 `b`를 참조함.

예시는 다음과 같다.

#include <iostream>

int main(void)
{
	int x = 1;

	auto getX = [=] { return x; };
	std::cout << getX() << std::endl; // == 1

	auto addX = [=](int y) { return x + y; };
	std::cout << addX(3) << std::endl; // == 4;

	auto getXRef = [&]() -> int& { return x; };
	int& y = getXRef();
	y = 6;
	std::cout << x << std::endl; // 6;
	return 0;
}

 

람다는 또한 함수의 인자로서 넣어질 수 있다. 마치 함수 포인터처럼 말이다.

std::vector<int> varr{0, 4, 6, 1, 3, 4};
std::sort(varr.begin(), varr.end(), [](int x, int y){return x < y;});
for (auto& it : varr)
	std::cout << it << ' '; // 0 1 3 4 4 6
std::cout << std::endl;

주의할 점

우선 디폴트로, "value-captures" 즉, 값으로 캡처 된 것은 남다 내부에서 변경하는 것이 금지 되어있다.

 

그 이유는, 컴파일러 생성 메서드는 `const`로 표시되기 때문이다.

 

하지만 "parameter-list" 이후에 `mutable` 키워드를 지정하게 될 시 "value-captured" 값을 바꿀 수 있게 된다.

auto f1 = [&x] { x = 2; }; // OK: x is a reference and modifies the original
auto f2 = [x] { x = 2; }; // error -- the lamda can only perform const-operations on the captured value
auto f3 = [x]() mutable { x = 6; }; // OK: the lamda can perform any operations on the captured value

 

'C++ > Modern C++(11, 14, 17, 20)' 카테고리의 다른 글

[C++11] Static Assertions  (0) 2023.08.26
[C++11] auto  (0) 2023.08.26
[C++11] decltype  (0) 2023.08.26
[C++11] Type aliases  (0) 2023.08.26
[C++11] nullptr  (0) 2023.08.26

관련글 더보기