C++11에서 람다 함수 매개변수는 구체적인 타입으로 선언해야 한다.
C++14에서는 이 요구 사항을 완화하여 람다 함수 매개 변수를 auto 타입 지정자로 선언할 수 있다.
auto lambda = [](auto x, auto y) {return x + y;};
auto 타입 추론과 관련하여 generic 람다는 템플릿 인수 추론 규칙을 따른다. (비슷하지만 모든 면에서 동일하지 않음)
위의 lambda의 변환 함수 동작은 아래 변환 함수 동작과 같다.
struct
{
template<typename T, typename U>
auto operator()(T x, U y) const {return x + y;}
} lambda{};
C++ 람다 표현식에 대해 자세히 알고 싶으면 아래 사이트를 참고하면 된다.
https://www.geeksforgeeks.org/lambda-expression-in-c/
C++14는 일반화된 람다(Generalized lambda)를 도입하여 람다 식을 더욱 강화하였다.
이 기능을 이해하기 위해 일반적인 예를 소개한다.
두 정수의 합을 반환하는 람다 함수를 생성한다.
[](int a, int b) -> int { return a + b; }
그러나 나중에 두 부동 소수점 값의 합을 구해야 한다면 어떻게 해야할까?
따라서 이중 값에만 사용할 수 있는 또 다른 람다 식을 선언해야 한다.
마찬가지로 입력 매개변수의 타입이 변경될 때마다 람다 함수를 다시 작성해야 했다.
[](double a, double b) -> double { return a + b; }
C++14 이전에는 템플릿 매개변수를 사용하여 이 문제를 우회하는 방법이 있었다.
template<typename T>
[](T a, T b) -> T { return a + b };
C++14는 이것을 없애고 람다 식의 입력 매개변수에서 키워드 auto를 사용할 수 있게 해준다.
따라서 컴파일러는 이제 컴파일 시간 동안 매개변수 타입을 추론할 수 있다.
이전 예에서 정수 및 부동 소수점 값 모두에 대해 작동하는 람다 표현식은 아래와 같다.
[](auto a, auto b) { return a + b; }
이 기능을 응용하여 기존 알고리즘을 크게 향상시킬 수 있다.
sort() 함수를 예로 들어보자. 다음 스니펫은 모든 데이터 타입(오버로드된 < 연산자가 있는 경우)을 내림차순으로 정렬한다.
sort(container.begin(), container.end(),
[](auto i, auto j) -> bool { return i > j; }
다음은 Generalized lambda를 사용하는 몇 가지 예제 프로그램이다.
// Cpp program to demonstrate
// generalized lambda expressions
#include <iostream>
#include <string>
using namespace std;
int main()
{
// Declare a generalized lambda and store it in sum
auto sum = [](auto a, auto b) {
return a + b;
};
// Find sum of two integers
cout << sum(1, 4) << endl;
// Find sum of two floating numbers
cout << sum(1.0, 6.6) << endl;
// Find sum of two strings
cout << sum(string("Geek"), string("ForGeek")) << endl;
return 0;
}
//Output : 5
// 7.6
// GeekForGeek
위의 예제는 auto를 사용한 a와 b를 합치는 람다식이다.
int, float, string을 각각 sum에 넣어도 제대로 된 결과가 나오는 것을 확인할 수 있다.
// Cpp program to demonstrate
// how to sort integers, floats, strings
// floating data types using a
// generalized lambda and sort function
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Utility Function to print the elements of a collection
void printElements(auto& C)
{
for (auto e : C)
cout << e << " ";
cout << endl;
}
int main()
{
// Declare a generalized lambda and store it in greater
auto greater = [](auto a, auto b) -> bool {
return a > b;
};
// Initialize a vector of integers
vector<int> vi = { 1, 4, 2, 1, 6, 62, 636 };
// Initialize a vector of doubles
vector<double> vd = { 4.62, 161.3, 62.26, 13.4, 235.5 };
// Initialize a vector of strings
vector<string> vs = { "Tom", "Harry", "Ram", "Shyam" };
// Sort integers
sort(vi.begin(), vi.end(), greater);
// Sort doubles
sort(vd.begin(), vd.end(), greater);
// Sort strings
sort(vs.begin(), vs.end(), greater);
printElements(vi);
printElements(vd);
printElements(vs);
return 0;
}
//Output : 636 62 6 4 2 1 1
// 235.5 161.3 62.26 13.4 4.62
// Tom Shyam Ram Harry
sort() 알고리즘의 연산자로 greater 람다를 넣어서 내림차순으로 소팅하는 예제이다. vector에 어떠한 타입이 들어와도 잘 동작되는 것을 확인할 수 있다.
https://www.geeksforgeeks.org/generalized-lambda-expressions-c14/
https://isocpp.org/wiki/faq/cpp14-language
http://en.cppreference.com/w/cpp/compiler_support
'C++ > C++14' 카테고리의 다른 글
C++14 : 람다 캡처 표현식(Lambda capture expressions) (0) | 2022.04.28 |
---|---|
C++14 : 숫자 구분자(Digit separators) (0) | 2022.04.15 |
C++14 : 바이너리 리터럴(Binary literals) (0) | 2022.04.15 |
C++14 : 애그리게이트 멤버 초기화(Aggregate member initialization) (0) | 2022.04.15 |
C++14 : 변수 템플릿(Variable templates) (0) | 2022.04.15 |
댓글