본문 바로가기
C++/C++14

C++14 : 제네릭 람다(Generic lambdas)

by 개발자J의일상 2022. 4. 15.
반응형

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/

 

Lambda expression in C++ - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

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

 

300x250

댓글