본문 바로가기
개발/Visual C++

C++ Lambda Expression (MSDN 자료)

by belitino 2014. 9. 4.

출처: http://msdn.microsoft.com/library/dd293608

 

출처를 읽고 정리한 글입니다.

 

람다라고도 불리는 람다식(lambda expression)은 익명 함수(anonymous function) 유사합니다. 익명 함수는 현재 상태를 유지하고 범위 내의 변수들을 접근할 있습니다.

 

본 글에서는 람다가 무엇인지를 정의하고, 다른 프로그래밍 기법들과 비교합니다. 그리고, 람다의 장점과 기본적인 예제를 제시합니다.

 

람다의 개요

많은 프로그래밍 언어들은 익명 함수(anonymous function) 개념을 지원합니다. 익명 함수는 함수의 내용은 있지만 이름이 없는 함수를 의미합니다. 람다는 익명 함수와 관련된 프로그래밍 기법입니다. 람다는 묵시적으로 함수 객체(function object) 클래스를 정의하고 클래스 타입의 함수 객체를 생성합니다. 함수 객체에 대해서는 MSDN Function object (http://msdn.microsoft.com/en-US/library/aa985932) 참고하시기 바랍니다.

 

C++ 표준에서는 람다가 std::sort() 함수에 전달되는 파라미터로 사용되는 예를 보여줍니다.

#include <algorithm>

#include <cmath>
void abssort(float* x, unsigned n) {
    std::sort(x, x + n,
       
// Lambda expression begins
        [](
float a, float b) {
           
return (std::abs(a) < std::abs(b));
        }
// end of lambda expression
    );
}

 

중요

람다는 다음과 같은 common language runtime(CLR) managed entity에서는 지원되지 않습니다: ref class, ref struct, value class, or value struct

 

함수 객체 vs. 람다

프로그램을 작성할 특히 STL algorithm 사용하는 경우에는 함수 포인터(function pointer) 함수 객체(function object) 사용할 것입니다. 함수 포인터와 함수 객체는 장단점을 갖고 있습니다. 예를 들어, 함수 포인터는 문법적 오버헤드를 최소화 하지만, 스코프에 해당하는 상태를 유지하지 않습니다. 함수 객체는 상태는 유지할 있지만 클래스 정의에 따르는 문법적 오버헤드가 있습니다.

 

람다는 함수 포인터와 함수 객체의 장점을 조합하고 이들의 단점을 제외한 것입니다. 람다는 함수 객체처럼 유연하며 상태를 유지할 있지만  함수 객체와는 다르게 클래스 정의가 필요하지 않습니다. 람다를 사용함으로써 함수 객체보다 간단하고 오류가 적게 발생하는 코드를 작성할 있습니다.

 

다음의 예는 람다와 함수 객체의 사용을 비교한 것입니다. 처음 예는 람다를 사용하여 vector 객체에 있는 요소들이 홀수인지 짝수인지 여부를 출력하는 프로그램이고 번째 예는 같은 작업을 함수 객체를 사용하여 수행하는 것입니다.

 

Example 1: 람다 사용

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

// even_lambda.cpp
// compile with: cl /EHsc /nologo /W4 /MTd
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
  
// Create a vector object that contains 10 elements.
   vector<
int> v;
  
for (int i = 1; i < 10; ++i) {
      v.push_back(i);
   }

// Count the number of even numbers in the vector by
  
// using the for_each function and a lambda.
  
int evenCount = 0;
   for_each(v.begin(), v.end(), [&evenCount] (
int n) {
      cout << n;
     
if (n % 2 == 0) {
         cout <<
" is even " << endl;
         ++evenCount;
      }
else {
         cout <<
" is odd " << endl;
      }
   });

// Print the count of even numbers to the console.
   cout <<
"There are " << evenCount
        <<
" even numbers in the vector." << endl;
}

 

Output

 

 

 

 

 

 

 

 

 

 

 

1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
There are 4 even numbers in the vector.

 

Comments

 

 

 

 

 

 

 

 

 

 

 

 

 

예제 1 for_each 함수의 세번째 인수가 람다입니다. [&evenCount] 람다식의 capture 입니다. (int n) 람다식의 인수이고, 나머지 부분은 람다식의 내용입니다.

 

Example 2: 함수 객체 사용

다음의 예제는 example 1 같은 결과를 내지만 람다 대신에 함수 객체를 사용한 것입니다. 예제 모두 vector  객체에 있는 짝수의 수를 저장합니다.

 

// even_functor.cpp
// compile with: /EHsc
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

class FunctorClass
{
public:
   
// The required constructor for this example.
   
explicit FunctorClass(int& evenCount)
        : m_evenCount(evenCount) { }

// The function-call operator prints whether the number is
   
// even or odd. If the number is even, this method updates
   
// the counter.
   
void operator()(int n) const {
        cout << n;

if (n % 2 == 0) {
            cout <<
" is even " << endl;
            ++m_evenCount;
        }
else {
            cout <<
" is odd " << endl;
        }
    }

private:
   
// Default assignment operator to silence warning C4512.
    FunctorClass&
operator=(const FunctorClass&);

int& m_evenCount; // the number of even variables in the vector.

};

 

int main()
{
   
// Create a vector object that contains 10 elements.
    vector<
int> v;
   
for (int i = 1; i < 10; ++i) {
        v.push_back(i);
    }

// Count the number of even numbers in the vector by
   
// using the for_each function and a function object.
   
int evenCount = 0;
    for_each(v.begin(), v.end(), FunctorClass(evenCount));

// Print the count of even numbers to the console.
    cout <<
"There are " << evenCount
        <<
" even numbers in the vector." << endl;
}

 

Summary

람다는 강력하고 표현력이 강한 프로그래밍 기법입니다. 람다의 문법에 대해서 공부를 하기 위해서는 Lambda Expression Syntax (http://msdn.microsoft.com/en-US/library/dd293603) 참고하시기 바랍니다. 람다의 사용법에 대해서는 Examples of Lambda Expression (http://msdn.microsoft.com/en-US/library/dd293599) 참고하시기 바랍니다.