- 람다 식이란 무엇입니까?
- Lambda Expression이라는 이름은 어디에서 왔습니까?
- 람다 식의 구문은 무엇입니까?
- 람다 식 구문의 다른 부분은 무엇입니까?
- 람다 식을 작성하는 다양한 방법은 무엇입니까?
- C++17에서 람다 표현식이 어떻게 변경되었습니까?
- 람다 식의 몇 가지 예는 무엇입니까?
- C++ 소프트웨어 Lambda Expression의 전체 예제가 있습니까?
- C++ 람다 식 사용의 장점은 무엇입니까?
- C++ 소프트웨어에서 람다 식을 사용할 때의 단점은 무엇입니까?
람다 식이란 무엇입니까?
람다 식은 사용되는 지점에서 익명 함수 또는 클로저를 정의합니다. 람다 식을 이름 없는 함수로 생각할 수 있습니다(그래서 "익명"이라고 합니다). 람다 식은 C++ 소프트웨어 코드를 더 깨끗하고 간결하게 만들고 함수와 같은 외부 메서드를 참조하는 대신 정의된 위치에서 동작을 인라인으로 볼 수 있도록 도와줍니다.
람다 식은 함수 개체를 반환하는 식입니다. 람다 식은 C++뿐만 아니라 C#, Groovy, Java, Python, Ruby 언어에서도 널리 사용됩니다.
Lambda Expression이라는 이름은 어디에서 왔습니까?
그리스 문자 람다( λ )는 이름이 없는 함수인 익명 함수를 나타내므로 "람다"라는 단어를 대신 사용합니다.
람다 식은 일반적으로 데이터 유형이 auto
함수 개체를 정의하는 변수에 할당할 수 있습니다.
람다 식의 구문은 = [ ] ( ) { … } 시리즈가 포함된 특정 구두점으로 구성됩니다.
람다 식은 최신 C++ 언어 기능 의 한 예입니다 . 이 문서의 목적은 람다 식, 식의 일부 및 코드를 작성하는 동안 사용할 수 있는 방법에 대한 정보를 제공하는 것입니다.
람다 식의 구문은 무엇입니까?
= [ ]
( )
{ ... }
람다 식의 구문은 일련 의 특정 구두점으로 구성됩니다 .
람다 식 의 기본 구문은 다음과 같습니다 .
Datatype Lambda Expression = [Capture Clause] (Parameter List) -> Return Type { Body } |
C++20 버전에서 Lambda Expression의 기본 구문은 다음과 같습니다.
Datatype Lambda Expression = [Capture Clause] <Template Parameters> (Parameter List) Specifier Exception Attribute -> Return Type { Body } |
여기;
- 데이터 유형 은 int, float, class 등과 같은 유형이며 대부분 자동 용어가 사용됩니다.
- Lambda Expression 은 사용자가 정의한 것입니다.
- Capture 절 에는 본문에 표시되는 변수가 있으며 캡처는 값 또는 참조로 발생할 수 있으며 비어 있을 수 있습니다.
- 매개변수 목록 은 비어 있거나 생략될 수 있습니다.
- 반환 유형 은 본문에서 반환하는 데이터 유형이며 선택 사항이며 일반적으로 추론됩니다.
- 본문 에는 실행할 프로그래밍 문이 포함되며 비어 있을 수 있습니다.
이제 하나하나 살펴보겠습니다.
람다 식 구문의 다른 부분은 무엇입니까?
람다 식의 데이터 유형
데이터 유형은 int, float
등과 같은 유형인 람다 표현식의 데이터 유형입니다. 최신 C++에서는 대부분 auto
용어가 사용됩니다.
람다 식
사용자가 정의한 표현입니다. 클래스 이름이나 메서드 이름처럼 사용됩니다.
람다 함수 C++ , 식의 일부 및 이 함수가 코드 작성 방식을 크게 개선하는 데 어떻게 도움이 되는지 알아보세요 .
람다 식의 캡처 절
Capture 절은 람다 메서드 본문 내에서 사용할 수 있도록 복사 또는 참조로 람다가 선언된 범위 내에서 표시되는 변수를 캡처하도록 컴파일러에 지시하는 데 사용됩니다. Capture 절은 함수의 요구 사항을 지정하기 위해 다양한 방식으로 사용될 수 있습니다.
capture 절은 대괄호로 묶인 람다의 첫 번째 부분입니다 []
.
캡처 절을 선언하는 몇 가지 방법은 다음과 같습니다.
- [ ] : 빈 캡처 . 아무 것도 캡처해서는 안된다는 의미입니다. 람다 식은 다음과 같이 작성할 수 있습니다.
auto L= [ ] ( ) { };
- [=]: 정의에서 값을 캡처합니다 . 함수 정의에 사용되는 모든 변수가 값으로 캡처되어야 함을 지정합니다. 값별 캡처를 기본 캡처 유형으로 만듭니다. 람다 식은 다음과 같이 작성할 수 있습니다.
auto L= [ = ] ( ) { };
- [ & ] : 사용 가치를 포착합니다. 함수 정의에 사용된 모든 변수가 참조로 캡처되어야 함을 지정합니다. 참조에 의한 캡처를 기본 캡처 유형으로 만듭니다. 람다 식은 다음과 같이 작성할 수 있습니다.
auto L= [ & ] ( ) { };
- [*this] : *this 캡처는 C++11에서 도입되었습니다. 목적은 현재 개체의 복사본을 캡처하거나 개체 자체를 캡처하는 것입니다. 값별 캡처 는 C++17에서 도입되었습니다. 값으로 [*this]를 캡처하는 것은 람다 식이 비정적 멤버 함수에서 비동기적으로 전달되는 시나리오에서 중요합니다. 함수가 실행될 때 포인터가 유효하지 않을 수 있습니다. 그런 이유로 *this를 값으로 포착할 수 있는 것이 중요합니다. 새로운 기능에 대한 자세한 내용은 여기에서 확인할 수 있습니다. *this by Value as의 Lambda 캡처
[*this]
[=,*this]
- 다중 캡처. 하나의 캡처 절에서
[=]
와 둘 다 함께 사용할 수 있습니다. 예를 들어 모든 변수는 복사로 캡처해야 하지만 변수 " "는 참조로 캡처하도록 지정합니다. 일부 캡처 절 정의는 중복으로 인해 오류가 발생합니다. 예를 들어, 다음과 같은 캡처 절 은 모든 변수가 참조로 캡처되어야 한다고 이미 지정한 다음 var가 참조로 캡처되어야 한다고 다시 지정했기 때문에 문제가 있습니다.[&]
****[=, &var]
var
[&, &var]
- 사본으로 캡처. 마찬가지로 참조로 모든 변수를 캡처하고 복사로 캡처할 특정 변수를 지정할 수 있습니다. 예를 들어,
[&, var]
모든 변수는 참조로 캡처해야 하지만 변수 "var
"는 복사로 캡처하도록 지정합니다.
람다 식 매개변수
람다의 매개변수 목록은 다른 메서드의 매개변수 목록과 같습니다: 중괄호 안의 매개변수 집합입니다 ()
. 람다 식의 입력 매개 변수는 람다 식을 정의하는 동안 나열할 수 있지만 필수는 아닙니다.
Lambda 표현식의 반환 유형
종종 반환 유형은 컴파일러에서 추론할 수 있기 때문에 지정할 필요가 없습니다. 단일 반환 문이 있는 경우 컴파일러는 반환 형식을 쉽게 추론할 수 있습니다. 더 복잡한 람다의 경우 명시적으로 지정해야 하거나 선택해야 할 수 있습니다.
람다 식의 본문
람다 식의 본문에는 일반 함수와 마찬가지로 코드가 포함되어 있습니다. {와 } 문자 사이에 정의됩니다.
C++ 람다 식, 식의 일부 및 코드를 작성하는 동안 사용할 수 있는 방법에 대한 정보를 얻으십시오 .
람다 식을 작성하는 다양한 방법은 무엇입니까?
Embarcadero의 C++Builder 를 사용하여 몇 가지 람다 표현식 스니펫을 추가했습니다 .
1. [ Captures ] ( Params ) -> ReturnType { Body };
이 방법에서는 일부 매개 변수와 반환 유형을 지정하는 캡처 절을 사용하고 있습니다.
샘플 코드:
#include <iostream> int main() { int pieces; auto total_area = [=] (int a, int b) -> int { return pieces*a*b; }; pieces = 10; std::cout << total_area( 8, 10 ); } |
이 코드가 의미하는 바는 모든 변수를 값으로 복사할 수 있어야 하며 함수의 반환 유형이 int라는 것입니다. 중괄호 안에 있는 명령문은 함수의 본문을 나타냅니다. 메서드는 람다 외부의 변수(값, 복사에 의해 캡처되어 const 값으로 사용 가능)와 일반 매개변수(a)를 모두 사용합니다.
이 람다의 경우 컴파일러는 반환 유형이 무엇인지 추론할 수 있지만 어쨌든 int로 지정했습니다.
2. [ Captures ] ( Params ) { Body };
이 방법에서는 캡처 절을 사용하고 일부 매개변수를 지정합니다. 반환 유형을 추론해야 합니다.
샘플 코드:
#include <iostream> int main() { int pieces; auto total_area = [&] (auto a, auto b) { return pieces*a*b; }; pieces = 10; std::cout << total_area( 8, 10 ); } |
이것이 의미하는 바는 모든 변수가 참조로 사용 가능해야 하고(다시 쓸 수 있음을 의미) 함수의 반환 유형이 추론되어야 한다는 것입니다. 중괄호 안에 있는 명령문은 함수의 본문을 나타냅니다.
일반적으로 캡처된 변수는 const 값 변수입니다. 사본이며 수정할 수 없습니다. 여기서 값은 참조로 캡처되므로 람다 내에서 "값"의 값을 수정할 수 있습니다.
삼. [ Captures ] { Body };
이 방법에서는 캡처 절을 사용하고 매개변수를 제외했습니다. 반환 유형을 추론해야 합니다.
샘플 코드:
#include <iostream> int main() { int pieces; auto total_area = [] { return pieces*8*10; }; pieces = 10; std::cout << total_area(); } |
람다 식은 capture 절을 지정하고 함수 본문을 정의하는 것만으로 작성할 수도 있습니다. 반환 유형을 지정하지 않으면 추론됩니다.
C++17에서 람다 표현식이 어떻게 변경되었습니까?
여러 기능이 C++17에서 업데이트되었습니다. C++17에서 람다 식에 적용된 몇 가지 변경 사항은 다음과 같습니다.
- 람다 식 소개
Constexpr
: 이제 람다 식을 constexpr로 선언할 수 있습니다. constexpr 키워드는 표현식이 컴파일 타임에 실행되도록 지정하는 데 사용할 수 있습니다. 람다 식은 constexpr로 선언된 경우 특정 규칙을 따라야 합니다. 식을 constexpr로 선언하면 식의 본문에 constexpr이 아닌 코드가 포함되어서는 안 됩니다. 예를 들어 메모리를 동적으로 할당하면 안 됩니다. - 람다 식에서 캡처
[*this]
: 람다 식에서[*this]
값으로 캡처는 C++17에서 도입되었습니다. C++17 이전에는 이 기능이 허용되지 않았으므로 복사본을 만들어 캡처해야 했습니다(오류가 발생하기 쉬움).
결론적으로 람다 식은 함수 작성에 대한 깔끔하고 간결한 대안을 제공합니다. 캡처 절과 매개 변수(선택 사항)를 사용하여 사용자 요구 사항에 따라 다양한 방식으로 선언할 수 있습니다. 또한 반환 유형을 추론할 수 있고 람다 식을 constexpr로 선언할 수 있습니다.
람다 식의 몇 가지 예는 무엇입니까?
이제 더 많은 구문 예제를 살펴보겠습니다. 데이터 유형을 결합하기 위해 람다 표현식을 정의합니다.
auto add_things = [](auto a, auto b) { return a + b; }; |
이것은 아래와 같이 모든 데이터 유형에 사용할 수 있습니다.
auto add_things = [](auto a, auto b) { return a + b; }; // Lambda Expression auto i = add_things(1, 2); std::string hello = "hello"; std::string world = "world"; auto s = add_things(hello, world); std::cout << i << std::endl; std::cout << s << std::endl; |
최신 C++ 소프트웨어에서는 C++ Builder VCL 또는 FMX 프로젝트 에서 UnicodeString 을 사용할 수 있습니다. 이 코드는 전 세계 언어를 지원합니다. 아래에서는 메모 구성 요소를 출력으로 사용했습니다.
auto add_things = [](auto a, auto b) { return a + b; }; // Lambda Expression auto i = add_things(1, 2); UnicodeString hello = L"hello"; UnicodeString world = L"world"; auto s = add_things(hello, world); Memo1->Lines->Add(i); Memo1->Lines->Add(s); |
C++ 소프트웨어 Lambda Expression의 전체 예제가 있습니까?
이것은 람다 식에 대한 전체 예제이며 3가지 다른 사용법이 있습니다. auto를 이해하는 것도 좋습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include <iostream> #include <tchar.h> auto LExp1 = [ ] (auto a, auto b) -> float { return a + b; }; auto LExp2 = [ ] (auto a, auto b) { return a + b; }; auto LExp3 = [ ] { return 0; }; int _tmain(int argc, _TCHAR* argv[]) { auto L1 = LExp1(3, 5); // L1 is float, because we define return type of Lexp1 is float std::string s1 = "LearnCPlusPlus"; std::string s2 = ".org"; auto L2 = LExp2(s1, s2); // L2 is string, because we didnt define return type, returns by auto datatype auto L3 = LExp3(); // returns 0; } |
람다 식에는 몇 가지 장점과 단점이 있습니다. 이제 살펴보겠습니다.
C++ 람다 식 사용의 장점은 무엇입니까?
람다 식은 사용되는 위치에서 바로 정의할 수 있는 가볍고 이름이 없는 함수입니다. 람다 식 기능은 함수형 프로그래밍 등과 같은 특정 목적 기능이 아닙니다. 람다 식을 사용하면 C와 유사한 함수 및 펑터 옆에 함수 인수를 람다로 지정할 수 있습니다. 둘 이상의 위치에서 사용할 수 있는 함수가 필요한 경우가 아니면 STL 구성 요소의 인수로 람다를 사용하는 것이 더 편할 것입니다. 이러한 기능으로 인해 Lambda Expression에는 몇 가지 장점이 있습니다.
- 람다는 메모리와 CPU 사용량이 저렴합니다. 람다 식의 비용은 동등한 클래스 또는 함수의 비용보다 결코 크지 않습니다.
- 그것들은 클래스를 사용하는 것과 동일합니다. 어셈블리 출력은 클래스를 사용하는 것과 동일합니다.
- 람다는 힙이 아닌 스택에 할당하므로 경우에 따라 이점이 있을 수 있습니다.
- Lambdas를 사용할 때 정적 변수를 캡처할 필요가 없습니다.
- 람다를 반환할 수 있습니다. 우리는 사용할 수
std::function
있습니다 - Lambda Expression에서 캡처된 변수는 기본적으로 변경할 수 없습니다.
- 람다 식을 복사하면 해당 상태가 복사됩니다.
- Lambda Expression에서 캡처
this
하는 것은 특별한 경우가 아닙니다. - 람다 식도 저렴합니다. 변수를 캡처하는 경우. 비용은 가상 조회 없이 개체를 구성하고 개체에서 직접 함수를 호출하는 것과 동일합니다.
C++ 소프트웨어에서 람다 식을 사용할 때의 단점은 무엇입니까?
람다 식은 C++11 표준(2011)에 도입되었으므로 이를 대체할 인라인 익명 펑터를 작성할 수 있으므로 struct f
여전히 개발자 사이에서 C++ 사용에 인기가 없습니다. 아래에 몇 가지 이유와 단점을 나열하려고 합니다.
- 개발자는 Lambda 표현식이 사용하기 복잡하다는 것을 알게 됩니다.
- 구문을 기억하기 어렵습니다. 개발자들은 구문이 혼란스럽고 표기법도 혼란스럽다고 생각합니다.
- 람다 정의 뒤에 무엇이 있는지 이해하기 어렵습니다(구조체 방식 또는 어셈블러 프로그래밍에서).
- 새로운 개발자는 람다 정의를 포함하여 새로운 코드 라인을 채택하는 데 어려움을 겪을 수 있습니다.
- 개발자는 '=' 및 '&' 캡처 기호를 착각할 수 있습니다. 경우에 따라 이 문제를 감지하는 데 많은 시간이 걸릴 수 있습니다. 이러한 종류의 문제는 디버깅 단계에서만 변수 변경으로 찾을 수 있습니다. ( 캡처 포인트의 & 기호는 변수의 주소를 가리키며, 사용 중인 변수의 값을 의미합니다. = 캡처 포인트의 기호는 정의에 있는 변수의 정확한 값을 나타냅니다. )
- 캡처 유형이 있는 람다 정의의 전역 및 로컬 사용에 잘못된 사용 오류가 있을 수 있음
- 람다는 힙이 아닌 스택에 할당하므로 경우에 따라 단점이 될 수 있습니다.
- 개발자가 변수를 캡처하지 않으면 람다 식은 문자 그대로 함수 호출과 같습니다. 즉, 이 유형에서 '저렴'(효율적)입니다.
- 일부 개발자가 [=] 및 [&]가 모든 주변 변수를 캡처한다고 생각할 수 있는 캡처에 대한 일반적인 오해가 있습니다. 사실 이것은 잘못된 것입니다! 함수 정의에 사용되는 모든 변수만 캡처 하고 더 이상 . 그러나 개발자는 캡처된 각 변수의 이름을 명시적으로 지정해야 합니다.
- 람다 식에서 클래스를 생성하는 경우 캡처할 때 동일한 수의 변수를 보유하는 동등한 클래스를 생성하는 것만큼 비용이 많이 듭니다(효율성 측면에서). 더 많은 변수(특히 값)를 캡처하면 생성된 펑터 클래스가 더 커지고 람다 사용 비용이 더 많이 듭니다. 또한 일반적으로 참조로 캡처하면 몇 가지 포인터에 지나지 않습니다.
출처 : https://blogs.embarcadero.com/the-advanced-guide-to-lambda-expression-in-c-software/
[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit