질문 : C ++ 11에서 람다식이 란 무엇입니까?
C ++ 11에서 람다식이 란 무엇입니까? 언제 사용합니까? 도입 전에는 불가능했던 문제의 종류는 무엇입니까?
몇 가지 예와 사용 사례가 유용 할 것입니다.
답변
std::for_each
및 std::transform
과 같은 유용한 일반 함수가 포함되어있어 매우 편리합니다. 안타깝게도 특히 적용하려는 펑터 가 특정 기능에 고유 한 경우 사용하기가 매우 번거로울 수 있습니다.
#include <algorithm>
#include <vector>
namespace {
struct f {
void operator()(int) {
// do something
}
};
}
void func(std::vector<int>& v) {
f f;
std::for_each(v.begin(), v.end(), f);
}
f
한 번만 사용하고 특정 위치에서 사소한 일을 한 번만 수행하기 위해 전체 클래스를 작성하는 것이 과도하게 보입니다.
C ++ 03에서는 functor를 로컬로 유지하기 위해 다음과 같이 작성하고 싶을 수 있습니다.
void func2(std::vector<int>& v) {
struct {
void operator()(int) {
// do something
}
} f;
std::for_each(v.begin(), v.end(), f);
}
그러나 이것은 허용되지 않습니다. f
는 C ++ 03 의 템플릿 함수에 전달할 수 없습니다.
새 솔루션
C ++ 11에서는 람다를 도입하여 인라인 익명 함수를 작성하여 struct f
를 대체 할 수 있습니다. 작은 간단한 예제의 경우 읽기가 더 깨끗하고 (모든 것을 한곳에 보관) 잠재적으로 유지 관리가 더 간단 할 수 있습니다 (예 : 가장 간단한 형식).
void func3(std::vector<int>& v) {
std::for_each(v.begin(), v.end(), [](int) { /* do something here*/ });
}
Lambda 함수는 익명의 펑터에 대한 구문 설탕 일뿐입니다.
간단한 경우에 람다의 반환 유형이 추론됩니다. 예 :
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) { return d < 0.00001 ? 0 : d; }
);
}
그러나 더 복잡한 람다를 작성하기 시작하면 컴파일러에서 반환 유형을 추론 할 수없는 경우가 빠르게 발생합니다. 예 :
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) {
if (d < 0.0001) {
return 0;
} else {
return d;
}
});
}
-> T
사용하여 람다 함수의 반환 유형을 명시 적으로 지정할 수 있습니다.
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) -> double {
if (d < 0.0001) {
return 0;
} else {
return d;
}
});
}
"Capturing" 변수
지금까지 우리는 그 안에서 람다에 전달 된 것 이외의 다른 것을 사용하지 않았지만, 람다 내에서 다른 변수를 사용할 수도 있습니다. 다른 변수에 액세스하려면 지금까지이 예제에서 사용되지 않은 []
void func5(std::vector<double>& v, const double& epsilon) {
std::transform(v.begin(), v.end(), v.begin(),
[epsilon](double d) -> double {
if (d < epsilon) {
return 0;
} else {
return d;
}
});
}
참조 및 값으로 캡처 할 수 있으며 각각 &
및 =
[&epsilon]
참조로 캡처[&]
는 람다에서 사용되는 모든 변수를 참조로 캡처합니다.[=]
는 람다에서 사용되는 모든 변수를 값으로 캡처합니다.[&, epsilon]
은 [&]와 같은 변수를 캡처하지만 값으로 epsilon을 캡처합니다.[=, &epsilon]
은 [=]와 같은 변수를 캡처하지만 참조로 엡실론을 캡처합니다.
생성 operator()
입니다 const
캡처 될 것이라는 의미로, 기본적으로 const
사용하면 기본적으로 그들에 액세스 할 때. 이것은 동일한 입력을 가진 각 호출이 동일한 결과를 생성하는 효과가 있지만 operator()
const
가 아닌 것을 요청하기 위해 람다를 mutable
으로 표시 할 수 있습니다.
출처 : https://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11
'프로그래밍 언어 > C++' 카테고리의 다른 글
C 또는 C ++를 사용하여 디렉토리의 파일 목록을 가져오는 방법 (0) | 2021.07.30 |
---|---|
C ++ 11은 표준화 된 메모리 모델의 도입이 미치는 영향 (0) | 2021.07.28 |
C ++ 17의 새로운 기능 (0) | 2021.07.27 |
메서드가 Moq에서 호출되지 않았는지 확인하는 방법 (0) | 2021.07.27 |
gcc의 C / C ++ 소스에서 assembler output 얻는 방법 (0) | 2021.07.27 |