0. Lambda란 ?

  • 람다 함수, 익명 함수 등으로 불림
  • 이름이 없는 함수, 1회성 함수, 메모리 공간을 차지하지 않는 함수(일반 함수들은 시작과 동시에 메모리에 올라간다고 함)

 

1. Lambda

  • 문법 : [](){}();
  • 순서대로 캡처, 매개변수, 구현, 인자
int AB = [](int a, int b) -> int { return a + b; }(1,2);  //3
  • -> int를 통해 반환값이 int임을 명시적으로 적어줄 수 있으며 (안 적어도 컴파일러가 알아서 추론해 줌)
  • a,b에 넘길 인자를 (1,2)를 통해 즉석에서 넘겨주어 함수를 호출한 모습
int (*Add)(int, int) = [](int a, int b) {return a + b; };
int Sum = Add(1, 2);
  • 위 코드와 같이 람다를 함수 포인터에 담아두었다가 함수 포인터를 호출하는 방식으로 사용할 수도 있고
auto Add = [](int a, int b) {return a + b; };
int Sum = Add(1, 2);
  • auto 키워드를 통해 번거로운 함수 포인터의 문법 걱정 없이도 람다를 담아둘 수 있다.
  • 4번째 괄호 ()가 있고 없고의 차이로 함수를 선언해둔건지 호출한건지에 차이를 둘 수 있다.

 

2. 캡처

  • 위 람다식에서 []에 대해선 언급을 안 했다.
  • 람다 함수를 작성하는 공간 기준으로 람다에겐 그 공간조차 외부일 수 있다. 그렇기 때문에 [], 캡처를 사용하여 그 지역의 변수를 복사 혹은 래퍼런스를 구해올 수 있다.
int a = 10;

[&a]()
{
	std::cout << a << std::endl;
	a = 20;
}();

std::cout << a << std::endl;
  • 위 코드와 같이 그 외부의 변수의 래퍼런스를 캡처에 담게 되면 캡처에 담은 변수는 람다 내에서 원본을 수정할 수 있게 된다.
int a = 10;

[a]()
{
	std::cout << a << std::endl;
	//a = 20;	//error
}();
  • 캡처가 아닌 복사로 갖고 오게 된다면 수정 조차 불가능하다. (우리가 함수에 인자를 넘길 때와는 조금 다르게 작용한다. 위 상황에선 a를 r value로 취급)
int a = 10;
int b = 20;

[&]()
{
	a = 20;
	b = 30;
}();

std::cout << a << std::endl;
std::cout << b << std::endl;
  • 특정 변수의 캡처를 하는 것이 아닌 &를 적게 되면 그 지역 내의 모든 변수를 래퍼런스로 사용하겠다는 의미이다. 람다 함수 내부에서 작성하는 코드가 사실 상 그 지역과 같다고 보면 된다.
  • 한 가지, Cpp가 아닌 언리얼에서 겪었던 고충이긴한데 포인터 변수에 대해 래퍼런스로 캡처해오고 그 람다함수를 타이머를 걸어서 래퍼런스로 알고 있던 포인터 변수(지역)가 파괴된 시점에 호출되며 에러를 일으킨 적이 있다. 이 경우엔 포인터가 가지고 있는 '주소' 자체를 '복사'로 가져와서 해결한 적이 있다.

 

3. 클로저

  • 클래스와 인스턴스의 차이가 람다와 클로저의 차이와 동일하다.
  • 클래스는 오직 소스코드에만 존재하고 런타임엔 인스턴스만이 존재한다.
  • 람다도 오직 소스코드에만 존재하고 런타임에 그 줄의 끝에서 파괴된다.
  • auto Add = [](int a, int b) {return a + b; }; 이 구문에서 = 의 오른쪽을 클로저라고 할 수 있다. Add를 클로저라고 착각할 수 있지만 Add는 클로저의 복사본일 뿐이라고 한다.
  • 위에서 언리얼에서 겪었던 문제가 사실 클로저를 몰랐기 때문에 생긴 문제이다.
  • 내가 참조로 가져온 포인터 변수(지역)는 클로저보다 먼저 그 지역이 파괴되면서 '댕글링'된 것이다. (포인터가 가리키는 원본이 댕글링이 되었다는 의미가 아님. 포인터를 참조한 래퍼런스가 댕글링 되었다는 뜻.)
  • 클로저의 수명은 보통 그 단락에서 끝나지만 위의 문제에선 클로저의 수명이 길어졌다라고 볼 수 있겠다.

https://lunchballer.com/archives/284

 

4. LinQ

  • C#의 문법으로 배열 등의 컨테이너에서 '질의'를 통해 원하는 데이터를 찾아오는 문법
  • 반복문, 조건문 등의 사용 없이 SQL 문법과 비슷하게 사용할 수 있음
  • .NET Framework 3.5 부터 도입 된 문법이라고 함
  • 언뜻 보기에도 간편해보임

'C++ > 키워드 정리' 카테고리의 다른 글

키워드 정리 [15] - SOLID  (2) 2023.12.01
키워드 정리 [14] - RTTI  (1) 2023.12.01
키워드 정리 [13] - 가상 함수  (0) 2023.12.01
키워드 정리 [12] - 클래스  (4) 2023.12.01
키워드 정리 [11] - OOP  (1) 2023.12.01

+ Recent posts