람다 표현식
1. 함수형 언어나 파이썬과 같은 인터프리터를 사용하는 언어에서 사용되던 클로저(Closure)가 네이티브 프로그래밍 언어에 도입되면서 람다 함수, 람다 표현식이 되었다.
2. 즉시 호출 형태로 사용하면 코드의 위치가 곧 호출 위치이므로 로직을 한눈에 파악할 수 있으며, 인라인(inline) 함수로 만들어 성능을 최적화하는 데도 도움이 된다.(인라인이 가능하면, 호출 오버헤드를 제거할 수 있다.)
3. 외부 변수 캡처 방법
- [=] : 선언부 범위의 모든 변수 읽기 전용으로 사용
- [&] : 선언부 범위의 모든 변수 참조 형식으로 사용되어 읽기와 쓰기 가능
- [변수 1] : 변수1을 읽기 전용으로 사용
4. 람다 표현식을 함수 객체로 사용하 때는 호출부를 작성하지 않는다. 또한 다른 함수나 객체에 매개변수로 전달할 경우 가급적 외부 변수를 캡처하지 않는 것이 좋다. 이유는 댕글링 포인터가 생길 수 있기 때문이다.
5. mutable 키워드를 이용하면 변수나 객체를 복사해서 가져올 수 있으므로, 람다 표현식 내부에서 변경된 값이 외부 변수에 영향을 주지 않는다.
예시) [&x] (int a, int b) mutable throw() -> int { return a + b; }(3, 4)
#include <iostream>
using namespace std;
const int loop_count = 5;
const int change_count = 5;
class vending_machine {
public:
vending_machine() : price{ 450, 390, 11340, 900, 150 } {};
void stack_drink() {};
void sale_using_basic_lambda(int payments[], int changes[]) {
for (int i = 0; i < loop_count; ++i) {
cout << payments[i] << "원을 내고 " << price[i] << "원 짜리 음료를 선택했습니다." << endl;
cout << "거슬러 받을 돈은 " << [&changes](int payment, int price)->int {
int change = payment - price;
changes[0] = change / 1000;
change %= 1000;
changes[1] = change / 500;
change %= 500;
changes[2] = change / 100;
change %= 100;
changes[3] = change / 50;
change %= 50;
changes[4] = change / 10;
return payment - price;
}(payments[i], price[i]) << "입니다." << endl;
cout << "천원 짜리 " << changes[0] << "개, 오백원 짜리 " << changes[1] << "개, 백원 짜리 " << changes[2] << "개, ";
cout << "오십원 짜리 " << changes[3] << "개, 십원 짜리" << changes[4] << "개로 받습니다." << endl;
}
};
private:
int price[loop_count];
};
int main() {
vending_machine vending_machine_object = vending_machine();
int payments[loop_count] = { 1000, 500, 15000, 1000, 200 };
int changes[change_count] = { 0, };
cout << "람다 표현식 기본 사용" << endl;
cout << "--------------------------------------------------------------------" << endl;
vending_machine_object.sale_using_basic_lambda(payments, changes);
return 0;
}
/*
출력 결과
람다 표현식 기본 사용
--------------------------------------------------------------------
1000원을 내고 450원 짜리 음료를 선택했습니다.
거슬러 받을 돈은 550입니다.
천원 짜리 0개, 오백원 짜리 1개, 백원 짜리 0개, 오십원 짜리 1개, 십원 짜리0개로 받습니다.
500원을 내고 390원 짜리 음료를 선택했습니다.
거슬러 받을 돈은 110입니다.
천원 짜리 0개, 오백원 짜리 0개, 백원 짜리 1개, 오십원 짜리 0개, 십원 짜리1개로 받습니다.
15000원을 내고 11340원 짜리 음료를 선택했습니다.
거슬러 받을 돈은 3660입니다.
천원 짜리 3개, 오백원 짜리 1개, 백원 짜리 1개, 오십원 짜리 1개, 십원 짜리1개로 받습니다.
1000원을 내고 900원 짜리 음료를 선택했습니다.
거슬러 받을 돈은 100입니다.
천원 짜리 0개, 오백원 짜리 0개, 백원 짜리 1개, 오십원 짜리 0개, 십원 짜리0개로 받습니다.
200원을 내고 150원 짜리 음료를 선택했습니다.
거슬러 받을 돈은 50입니다.
천원 짜리 0개, 오백원 짜리 0개, 백원 짜리 0개, 오십원 짜리 1개, 십원 짜리0개로 받습니다.
*/
#include <iostream>
using namespace std;
const int loop_count = 5;
const int change_count = 5;
class vending_machine {
public:
vending_machine() : price{ 450, 390, 11340, 900, 150 } {};
void stack_drink() {};
void sale_sale_using_lambda_function_object(int payments[], int changes[]) {
auto calcu_changes = [&changes](int payment, int price)->int {
int change = payment - price;
changes[0] = change / 1000;
change %= 1000;
changes[1] = change / 500;
change %= 500;
changes[2] = change / 100;
change %= 100;
changes[3] = change / 50;
change %= 50;
changes[4] = change / 10;
return payment - price;
};
for (int i = 0; i < loop_count; ++i) {
cout << payments[i] << "원을 내고 " << price[i] << "원 짜리 음료를 선택했습니다." << endl;
cout << "거슬러 받을 돈은 " << calcu_changes(payments[i], price[i]) << "입니다." << endl;
cout << "천원 짜리 " << changes[0] << "개, 오백원 짜리 " << changes[1] << "개, 백원 짜리 " << changes[2] << "개, ";
cout << "오십원 짜리 " << changes[3] << "개, 십원 짜리" << changes[4] << "개로 받습니다." << endl;
}
};
private:
int price[loop_count];
};
int main() {
vending_machine vending_machine_object = vending_machine();
int payments[loop_count] = { 1000, 500, 15000, 1000, 200 };
int changes[change_count] = { 0, };
cout << endl << "람다 표현식 함수 객체로 사용하기" << endl;
cout << "--------------------------------------------------------------------" << endl;
vending_machine_object.sale_sale_using_lambda_function_object(payments, changes);
return 0;
}
/*
출력 결과
람다 표현식 함수 객체로 사용하기
--------------------------------------------------------------------
1000원을 내고 450원 짜리 음료를 선택했습니다.
거슬러 받을 돈은 550입니다.
천원 짜리 0개, 오백원 짜리 1개, 백원 짜리 0개, 오십원 짜리 1개, 십원 짜리0개로 받습니다.
500원을 내고 390원 짜리 음료를 선택했습니다.
거슬러 받을 돈은 110입니다.
천원 짜리 0개, 오백원 짜리 0개, 백원 짜리 1개, 오십원 짜리 0개, 십원 짜리1개로 받습니다.
15000원을 내고 11340원 짜리 음료를 선택했습니다.
거슬러 받을 돈은 3660입니다.
천원 짜리 3개, 오백원 짜리 1개, 백원 짜리 1개, 오십원 짜리 1개, 십원 짜리1개로 받습니다.
1000원을 내고 900원 짜리 음료를 선택했습니다.
거슬러 받을 돈은 100입니다.
천원 짜리 0개, 오백원 짜리 0개, 백원 짜리 1개, 오십원 짜리 0개, 십원 짜리0개로 받습니다.
200원을 내고 150원 짜리 음료를 선택했습니다.
거슬러 받을 돈은 50입니다.
천원 짜리 0개, 오백원 짜리 0개, 백원 짜리 0개, 오십원 짜리 1개, 십원 짜리0개로 받습니다.
*/