본문 바로가기

진리는어디에/C++

[C++] 제네릭 람다 표현식

들어가며

이번 포스트에서는 C++14 부터 포함된 제네릭 람다 표현식에 대해 살펴 보도록 하겠다. 제네릭 람다 표현식은 auto 키워드를 이용해 하나의 람다 표현식 코드로 다양한 타입의 인자들에 대해 대응할 수 있는 람다 표현식을 말한다.

일반 람다 표현식 vs 제네릭 람다 표현식

먼저 일반적인 람다 표현식과 그 사용을 살펴 보자.

auto add = [](int a, int b) { return a + b; };

std::cout << add(1, 1) << std::endl;
std::cout << add(1.1, 1.2) << std::endl;
std::cout << add(1, 1.4) << std::endl;

C++에서 실수는 정수로 암묵적 캐스팅 되기 때문에 위 예제 코드를 컴파일하면 정상적으로 컴파일 된다. 하지만 1.1과 같은 실수가 모두 1로 다운 캐스팅 되었기 때문에 위 프로그램의 실행 결과는 모두 2다.

C++14 부터는 람다 표현식의 인자로 auto를 사용할 수 있게 변경 되었다. 아래 처럼 람다 표현식의 인자로 auto를 사용하게 되면 각 값에 맞는 타입으로 연산 되어 정확한 결과를 얻을 수 있다.

auto add = [](auto a, auto b) { return a + b; };

std::cout << add(1, 1) << std::endl;      // 2
std::cout << add(1.1, 1.2) << std::endl;  // 2.3
std::cout << add(1, 1.4) << std::endl;    // 2.4

위와 같이 람다 표현식의 인자에 auto를 적용하여 다양한 타입에 대응하는 괄호 연산자 함수를 생성해 낼 수 있도록 하는것을 '제네릭 람다 표현식'이라고 한다.

위 코드가 컴파일러에 의해 함수자 클래스로 생성되는 것을 보면 괄호 연산자 오버로딩에 템플릿이 추가 되어 아래와 같은 형태의 코드가 생성된다.

class __lambda_5_16
{
public: 
    template<class type_parameter_0_0, class type_parameter_0_1>
    inline /*constexpr */ auto operator()(type_parameter_0_0 a, type_parameter_0_1 b) const
    {
      return a + b;
    }
    
    template<>
    inline /*constexpr */ int operator()<int, int>(int a, int b) const
    {
      return a + b;
    }

    template<>
    inline /*constexpr */ double operator()<double, double>(double a, double b) const
    {
      return a + b;
    }
    
    template<>
    inline /*constexpr */ double operator()<int, double>(int a, double b) const
    {
      return static_cast<double>(a) + b;
    }
    // ... 생략 ...    
};

__lambda_5_16 add = __lambda_5_16{};
std::cout.operator<<(add.operator()(1, 1)).operator<<(std::endl);
std::cout.operator<<(add.operator()(1.1000000000000001, 1.2)).operator<<(std::endl);
std::cout.operator<<(add.operator()(1, 1.3999999999999999)).operator<<(std::endl);

(출저 : https://cppinsights.io/ 에서 코드 변환)

마치며

이상 C++14 부터 포함된 제네릭 람다 표현식에 대해 살펴 보았다. 핵심은 auto를 사용하는 경우 내부적으로 템플릿 함수로 변경 되며 각 타입별로 템플릿 인자가 지정된다는 것이다. 다음 포스트에서는 '템플릿 람다 표현식'에 대해 자세히 알아 보도록 하겠다.

부록 1. 같이 읽으면 좋은 글

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!