C++ 픽업 - lambda 표현식 원리
전언
lambda 표현식은 C++11의 새로운 표준에서 제시된 것입니다.lambda 표현식에서 우리는 그것의 사용을 집중적으로 정리했다.지금 그것의 실현 원리를 토론해 봅시다.
본문
1. 함수 대상
클래스의 대상은 괄호와 결합하여 함수의 일반적인 행위를 나타내는데 이 대상을 함수 대상이라고 할 수 있다.#include <iostream>
using namespace std;
class MyClass
{
public:
// ()
int operator()(int i)
{
return i;
}
};
int main()
{
MyClass my;
//my()
int i = my(1); // my.operator()(1)
cout << "i = " << i << endl;
cin.get();
return 0;
}
실행
이 예는 함수 대상의 본질이 함수 호출 연산자를 다시 불러온 것을 설명한다.하나의 클래스가 함수 호출 연산자 ()를 다시 불러오면 그 대상은 함수 대상이 된다.이것은 lambda 표현식 내부의 실현을 이해하는 기초이다.
2. lambda 표현식 원리
원리: 컴파일러는 lambda 표현식을 익명 클래스의 익명 대상으로 만들고 클래스에서 함수를 다시 불러와 연산자를 호출합니다.
우리 는 가장 간단한 lambda 표현식 에서 착안하여, 쉬운 것 부터 어려운 것 까지
2.1 캡처 목록 및 매개변수 목록 없음
auto print = []{cout << "zhangxiang" << endl; };
컴파일러는 이 문장을 다음과 같은 상황으로 번역할 것이다.// lambda
class print_class
{
public:
void operator()(void) const
{
cout << "zhangxiang" << endl;
}
};
// ,print
auto print = print_class();
클래스를 생성하는 클래스 이름 규칙은 다변적일 수 있습니다. 꼭 그렇지는 않습니다.
2.2 캡처 목록은 없지만 매개 변수 목록이 있음
auto add = [](int a, int b){return a + b; };
컴파일러는 이 문장을 다음과 같은 상황으로 번역할 것이다.class add_class
{
public:
auto operator()(int a, int b) const
{
return a + b;
}
};
auto add = add_class();
2.3 캡처 목록, 매개변수 목록 옵션
포획 방식은 두 가지로 나뉘는데 그것이 바로 인용포획, 값포획이기 때문에 이런 상황에서 세분화할 수 있다.
2.3.1 값 캡처
int year = 19900212;
char *name = "zhangxiang";
// , , year,name
auto print = [=](){
cout << year << ends << name << endl;
};
번역하다int year = 19900212;
char *name = "zhangxiang";
class print_class
{
public:
//
print_class(int year, char *name) :year(year), name(name)
{
}
void operator()(void) const
{
cout << year << ends << name << endl;
}
private:
int year;
char *name;
};
auto print = print_class(a, str);
운행 효과가 같으니 시범을 보이지 않겠다.
2.3.2 참조 캡처
int year = 19900212;
char *name = "zhangxiang";
auto print = [&](){
year++;
cout << year << ends << name << endl;
};
번역하다int year = 19900212;
char *name = "zhangxiang";
class print_class
{
public:
// ,
print_class(int &year, char *&name) :year(year), name(name)
{
}
void operator()(void) const
{
year++; // ,const
cout << year << ends << name << endl;
}
private:
int &year;
char *&name;
};
테스트를 통해 효과도 마찬가지다.
2.3.3 블렌드 캡처
int year = 19900212;
int shoes = 42;
char *name = "zhangxiang";
auto show = [&, shoes]()mutable{
shoes++;
year++;
cout << year << ends << shoes << ends << name << endl;
};
번역하다int year = 19900212;
int shoes = 42;
char *name = "zhangxiang";
class show_class
{
private:
int &year;
mutable int shoes;
char *&name;
public:
show_class(int &year, int shoes, char *&name) :year(year), shoes(shoes), name(name)
{
}
void operator()(void)const
{
shoes++;
year++;
cout << year << ends << shoes << ends << name << endl;
}
};
auto show = show_class(year, shoes, name);
show();
기본적으로 값을 통해 포획된 변수는 파라미터 목록 뒤에 키워드mutable을 추가하지 않으면 수정할 수 없습니다.상기 코드는 클래스에 대응하는mutable가 어떻게 추가되었는지 보여 줍니다.물론 lambda 표현식에 mutable를 추가하면 함수를 다시 불러올 때 const 수식을 하지 않는 또 다른 실현 방법도 있다.
총결산
이상의 예시 코드는 기본적으로 각종 상황의 lambda 표현식의 실현 원리를 모두 보여 주었기 때문에 자세히 생각해 보면 매우 쉽다.
본 칼럼 목록
1. 함수 대상
클래스의 대상은 괄호와 결합하여 함수의 일반적인 행위를 나타내는데 이 대상을 함수 대상이라고 할 수 있다.
#include <iostream>
using namespace std;
class MyClass
{
public:
// ()
int operator()(int i)
{
return i;
}
};
int main()
{
MyClass my;
//my()
int i = my(1); // my.operator()(1)
cout << "i = " << i << endl;
cin.get();
return 0;
}
실행
이 예는 함수 대상의 본질이 함수 호출 연산자를 다시 불러온 것을 설명한다.하나의 클래스가 함수 호출 연산자 ()를 다시 불러오면 그 대상은 함수 대상이 된다.이것은 lambda 표현식 내부의 실현을 이해하는 기초이다.
2. lambda 표현식 원리
원리: 컴파일러는 lambda 표현식을 익명 클래스의 익명 대상으로 만들고 클래스에서 함수를 다시 불러와 연산자를 호출합니다.
우리 는 가장 간단한 lambda 표현식 에서 착안하여, 쉬운 것 부터 어려운 것 까지
2.1 캡처 목록 및 매개변수 목록 없음
auto print = []{cout << "zhangxiang" << endl; };
컴파일러는 이 문장을 다음과 같은 상황으로 번역할 것이다.
// lambda
class print_class
{
public:
void operator()(void) const
{
cout << "zhangxiang" << endl;
}
};
// ,print
auto print = print_class();
클래스를 생성하는 클래스 이름 규칙은 다변적일 수 있습니다. 꼭 그렇지는 않습니다.
2.2 캡처 목록은 없지만 매개 변수 목록이 있음
auto add = [](int a, int b){return a + b; };
컴파일러는 이 문장을 다음과 같은 상황으로 번역할 것이다.
class add_class
{
public:
auto operator()(int a, int b) const
{
return a + b;
}
};
auto add = add_class();
2.3 캡처 목록, 매개변수 목록 옵션
포획 방식은 두 가지로 나뉘는데 그것이 바로 인용포획, 값포획이기 때문에 이런 상황에서 세분화할 수 있다.
2.3.1 값 캡처
int year = 19900212;
char *name = "zhangxiang";
// , , year,name
auto print = [=](){
cout << year << ends << name << endl;
};
번역하다
int year = 19900212;
char *name = "zhangxiang";
class print_class
{
public:
//
print_class(int year, char *name) :year(year), name(name)
{
}
void operator()(void) const
{
cout << year << ends << name << endl;
}
private:
int year;
char *name;
};
auto print = print_class(a, str);
운행 효과가 같으니 시범을 보이지 않겠다.
2.3.2 참조 캡처
int year = 19900212;
char *name = "zhangxiang";
auto print = [&](){
year++;
cout << year << ends << name << endl;
};
번역하다
int year = 19900212;
char *name = "zhangxiang";
class print_class
{
public:
// ,
print_class(int &year, char *&name) :year(year), name(name)
{
}
void operator()(void) const
{
year++; // ,const
cout << year << ends << name << endl;
}
private:
int &year;
char *&name;
};
테스트를 통해 효과도 마찬가지다.
2.3.3 블렌드 캡처
int year = 19900212;
int shoes = 42;
char *name = "zhangxiang";
auto show = [&, shoes]()mutable{
shoes++;
year++;
cout << year << ends << shoes << ends << name << endl;
};
번역하다
int year = 19900212;
int shoes = 42;
char *name = "zhangxiang";
class show_class
{
private:
int &year;
mutable int shoes;
char *&name;
public:
show_class(int &year, int shoes, char *&name) :year(year), shoes(shoes), name(name)
{
}
void operator()(void)const
{
shoes++;
year++;
cout << year << ends << shoes << ends << name << endl;
}
};
auto show = show_class(year, shoes, name);
show();
기본적으로 값을 통해 포획된 변수는 파라미터 목록 뒤에 키워드mutable을 추가하지 않으면 수정할 수 없습니다.상기 코드는 클래스에 대응하는mutable가 어떻게 추가되었는지 보여 줍니다.물론 lambda 표현식에 mutable를 추가하면 함수를 다시 불러올 때 const 수식을 하지 않는 또 다른 실현 방법도 있다.
총결산
이상의 예시 코드는 기본적으로 각종 상황의 lambda 표현식의 실현 원리를 모두 보여 주었기 때문에 자세히 생각해 보면 매우 쉽다.
본 칼럼 목록
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Lambda Cron 예제(Terraform)이 기사에서는 EventBridge를 사용하여 일정에 따라 람다를 트리거하는 방법을 살펴보겠습니다. Terraform을 사용하여 이를 구현할 것입니다. 이 예제에서는 간단한 Golang Hello World 예제를 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.