lambda
는 C++11부터 지원이 되었으며 Functor나 for-each를 이용한 반복등을 이용한 함수를 깔끔하고 쉽게 만들기 위한것이다.
Functor
는 함수처럼 동작하는 클래스를 의미하며 ‘함수 오브젝트(Funtion Object)’라고도 불린다. 즉 operator()를 정의하고 이를 이용해서 표현되어있다.
class FunctorClass
{
public:
return-type operator () ( parameters... )
{
// do something...
}
};
#include <iostream>
using namespace std;
class Point
{
int xpos, ypos;
public :
Point(int x = 0, int y = 0) : xpos(x), ypos(y) {}
Point operator+(const Point &pos) const
{
return Point(xpos + pos.xpos, ypos + pos.ypos);
}
friend ostream& operator<<(ostream &os, const Point &pos);
};
class Adder
{
public :
Point operator()(const Point &pos1, const Point &pos2)
{
return pos1 + pos2;
}
};
ostream& operator<<(ostream &os, const Point &pos)
{
os << '[' << pos.xpos << ", " << pos.ypos << ']' << endl;
return os;
}
int main(){
Adder adder;
cout << adder(Point(5, 4), Point(6, 10));
return 0;
}
위의 예제처럼 Functor는 함수 또는 객체의 동작방식에 유연함을 제공할 때 주로 사용된다.
위의 사진처럼 람다는
[변수 캡쳐](받을 인자)->리턴타입{함수}(넘길 인자)
의 형태를 띄고 있다.
int main(){
int a = 10;
int b = 20;
int c = 30;
int result = [](int a, int b)->int {return a + b; }(a, b);
int result2 = [=]()->int {return a + b; }();
int result3 = [=,&a,&b]()->int {return a + b+c; }();
auto result4 = [](int d)->decltype(auto) {return d * 30; }(a);// a를 대입해서 나온결과값이 result4
int result5 = [a, &b]()->int {return a + b;}();
auto result6 = [](int d)->decltype(auto) {return d * 30; };//result6는 함수 포인터
[&b](){ b *= 6; }();// =>동일 [](int &v) {v *= 6;}(b);
//[b]() {b *= 6; }();//err! 참조가 아닌 값으로 가져와 *만 할 수 없음
std::cout << "result : " << result << std::endl;
std::cout << "result2 : " << result2 << std::endl;
std::cout << "result3 : " << result3 << std::endl;
std::cout << "result4 : " << result4 << std::endl;
std::cout << "result5 : " << result5 << std::endl;
std::cout << "a : " << a << std::endl;//a : 10
std::cout << "b : " << b << std::endl;//b : 120
std::cout << result6(10) << std::endl;
}
[변수 캡쳐] : 현재 람다 함수에서 사용할 외부의 변수를 의미한다.
(받을 인자) : 부분은 말 그대로 함수에서 받는 인자들이다
void func(int a, int b)
에서(int a, int b)
부분이다. 받을 인자가 없다면()
로 두면 된다.
->리턴타입 : void, int 와 같이 함수의 리턴형을 명시하는 부분이다.
void라면 ->와 함깨 생략 가능하다. delctype(auto)와 같이 타입 추론형식도 사용가능하다.
{함수} : 함수의 몸체 영역으로 만들고자 하는 코드의 구현부분이 들어가는부분이다.
(넘길 인자) : 호출하는 함수에서 넘겨주는 값들이다 func(3,5);
에서 3,5를 넘겨주는것과 같다.
int a = 10, b = 20;
int result = [&]()->int{
return [&]()->int{ return a+b;}();
}();
람다 함수 내부에 또다른 람다 함수를 중복 시킬 수 있다.
class Adder {
private:
int a;
public:
Adder(int a) {
this->a = a;
}
int addNum(int num) {
return [=]()->int { return a + num; }();
}
int addNum2(int num) {
return [&]()->int { return a + num; }();
}
};
클래스 내부에서도 람다 함수를 이용한 함수를 구현 할 수 있다.
auto myFunction = []{std::cout << "This is my function"<< std::endl;};
myFunction();
위의 코드처럼 myFunction가 함수포인터의 형태로 람다 표현식을 가질 수 있음을 확인가능하다.
int i=10;
auto myFunc = [=]()mutable ->int {
i*=5;
return i;
};
std::cout << myFunc() << " " << i << std::endl;
i값을 람다 함수 내에서만 변경하고 싶은경우 리턴타입 전에 mutable
키워드를 사용하면 내부에서만 변경값이 적용된다. 참조가 아닌 값복사를 이용한 변수 변경을 위해서는 mutable
을 붙여주어야 하는 것이다.
위의 코드를 실행하면 결과값으로 50 10
이 출력된다.
https://docs.microsoft.com/ko-kr/cpp/cpp/examples-of-lambda-expressions?view=vs-2019 https://modoocode.com/196