Lambda 람다 - 이름이 없는 함수
람다를 써야하는 대표적인 이유는
재사용이 되지 않을 어떤 함수를 작성하기 위함이다.
#include <iostream>
#include <array>
using namespace std;
bool DescendingSort(int a, int b)
{
return a > b;
}
int main(void)
{
array<int, 3> arr;
for (int i = 0; i < 3; ++i)
{
arr[i] = i + 10;
}
sort(arr.begin(), arr.end(), DescendingSort);
for (int num : arr)
{
cout << num << endl;
}
system("pause");
return 0;
}
위의 코드에서 DescendingSort가 다시는 사용되지 않을 코드라면,
저것은 오히려 유지보수 측면에서 안좋은 영향을 끼친다.
그렇기에 람다를 써서 아래와 같이 작성을 해준다.
#include <iostream>
#include <array>
using namespace std;
int main(void)
{
array<int, 3> arr;
for (int i = 0; i < 3; ++i)
{
arr[i] = i + 10;
}
sort(arr.begin(), arr.end(), [](int a, int b) {return a > b; });
for (int num : arr)
{
cout << num << endl;
}
system("pause");
return 0;
}
이렇기 작성을 하더라도 같은 결과를 반환한다.
람다의 정의는 다음과 같다.
[ captures ] ( params ) <specifiers> -> <return_type> { body } |
capture는 람다식을 포함하고 있는 범위에 있는 변수를 가져올때 사용한다.
params는 매개변수를 받는 곳이다.
specifiers는 지정자로서 mutable, constexpr, consteval(C++20에서 추가가되었다)라는 키워드들이 있다.
capture의 종류
- = 부모함수에 있는 변수를 전부 값으로 가져온다. 람다식 내부에서 수정할수가 없다.
- & 참조로 변수를 가져온다.
=캡처 예)
#include <iostream>
#include <array>
using namespace std;
int main(void)
{
int value1 = 10;
int value2 = 20;
auto add = [=]() {return value1 + value2; };
cout << add() << endl;
system("pause");
return 0;
}
=를 사용하여, 부모함수에 있는 변수 value1과 value2를 람다에서 값으로서 사용이 가능하게 됐다.
람다함수 내부에서는 value1과 value2의 값을 수정하려고 하면, 에러가 발생한다.
&캡처 예)
#include <iostream>
#include <array>
using namespace std;
int main(void)
{
int value1 = 10;
int value2 = 20;
auto add = [&]() {
value1 = 1000;
value2 = 2000;
return value1 + value2;
};
cout << add() << endl;
cout << value1 << endl;//1000
cout << value2 << endl;//2000
system("pause");
return 0;
}
&를 사용해서 람다함수 내부에서 값을 바꾸었다.
특정 변수 값들 캡처 예)
#include <iostream>
using namespace std;
int main(void)
{
int value1 = 10;
int value2 = 20;
auto add = [value1, value2]()
{
return value1 + value2;
};
cout << add() << endl;
cout << value1 << endl;//10
cout << value2 << endl;//20
system("pause");
return 0;
}
특정 변수들 참조 캡처 예)
#include <iostream>
using namespace std;
int main(void)
{
int value1 = 10;
int value2 = 20;
auto add = [&value1, &value2]()
{
value1 = 1000;
value2 = 2000;
return value1 + value2;
};
cout << add() << endl;
cout << value1 << endl;//1000
cout << value2 << endl;//2000
system("pause");
return 0;
}
값 캡처와 참조 캡처 예)
#include <iostream>
using namespace std;
int main(void)
{
int value1 = 10;
int value2 = 20;
int value3 = 30;
int value4 = 40;
auto add = [=, &value1, &value2]()
{
value1 = 1000;
value2 = 2000;
// value3 = 3000; // error
// value4 = 4000; // error
return value1 + value2 + value3 + value4;
};
cout << add() << endl;
cout << value1 << endl;//1000
cout << value2 << endl;//2000
cout << value3 << endl;//30
cout << value4 << endl;//40
system("pause");
return 0;
}
Specifiers 키워드들의 종류와 설명
mutable은 참조가 아닌 값으로 캡처해온 변수들을 람다 내부에서 바꿀수 있게해준다.
constexpr은 함수를 constexpr함수로 만들어 준다. 즉 리턴값을 Compile타임 상수로 만들수 있다.
consteval은 상수를 만들기 위해서 compile타임에 평가를 한다. - 사실 아직 뭔지 잘 모르겠다.
'Programming > C C++' 카테고리의 다른 글
operator Overloading (0) | 2021.01.07 |
---|---|
Garbage Collection & Reference Counting (0) | 2020.10.22 |
prefix increment operator vs. postfix increment operator (0) | 2020.10.12 |
C++ 정적 바인딩과 동적 바인딩 (0) | 2020.09.29 |