c + + 0x 학습 노트 lambda

회전:http://feng.free.lc/?m=201104
 
lambda 의 지원 을 받 은 후에 함수 식 코드 를 쓰 는 것 이 더욱 편리 해 졌 다. 예 를 들 어
std::vector<int> vec;
std::for_each( vec.begin(), vec.end(),
               [](int i){ std::cout <<i << "\t"; } );

예컨대
std::sort( vec.begin(), vec.end(), [](int i, int j)
           { return std::abs(i) < std::abs(j); } );

그 중의
[](int i, int j){return std::abs(i) < std::abs(j);}

람 다 대상 이 야.이 익명 의 대상 이 되 돌아 오 는 유형 은?
decltype(std::abs(j)<std::abs(j))

특히 lambda 대상 에 return expression 이 있 을 때 반환 형식 을 무시 할 수 있 습 니 다. 그렇지 않 으 면 void 입 니 다.그래서 이 lambda 대상 은 완전히 이렇게 적 혀 있다.
[](int i, int j) -> bool
{ return std::abs(i) < std::abs(j); }

이 중 [] 을 lambda 가이드 문자 (lambda - introducer) 라 고 부 릅 니 다. 안쪽 은 비어 있 을 수도 있 고 몇 개의 변수 이름 이 있 을 수도 있 습 니 다.
[] / / 매개 변수 가 정의 되 지 않 았 습 니 다.
[x, & y] / / x 는 값 으로 들 어 오고 y 는 인용 으로 들 어 옵 니 다.
[&] / / 모든 외부 매개 변 수 는 인용 으로 전 달 됩 니 다.
[=] / / 모든 외부 매개 변 수 는 값 으로 전 달 됩 니 다.
[&, x] / / x 는 값 으로 들 어 오고 나머지 는 인용 으로 들 어 옵 니 다.
[=, & z] / / z 는 인용 으로 들 어 오고 나머지 는 값 으로 들 어 옵 니 다.
다음은 외부 인 자 를 사용 하 는 예 입 니 다.
std::vector<double> arr;
double sum = 0;
std::for_each( arr.begin(), arr.end(),
               [&sum](double d){ sum += std::exp(d); } );

그 중 sum 은 인용 으로 들 어 와 계산 에 해당 합 니 다.
결 과 를 sum 에 저장 합 니 다.
물론 위 에서 도 모든 외부 매개 변수의 인용 을 직접 캡 처 하여 간소화 할 수 있 습 니 다. 이것 은 매개 변수 가 많 을 때 유용 합 니 다.
 
std::for_each( arr.begin(), arr.end(),
               [&](double d) { sum+= std::exp(d); } );

 
한편, lambda 표현 식 의 () 의 하위 인자 (parameter - declaration - clause) 는 개수 가 0 일 때 무시 할 수 있 습 니 다.
따라서 아래 의 이 지루 한 코드 도 컴 파일 을 통 해
[]{}();

그 중에서 [] {} 은 익명 의 lambda 대상 을 밝 혔 습 니 다. 0 개의 인 자 를 캡 처 하여 0 개의 인 자 를 입력 하고 어떠한 동작 도 수행 하지 않 고 void 로 돌아 갑 니 다. 즉,
[]()->void{}

게다가 뒤에 있 는 () 은 이 lambda 대상 이 한 번 실 행 했 음 을 나타 낸다.
 
한 클래스 에서 lambda 는 클래스 의 다른 대상 을 잡 아야 합 니 다. 이 럴 때 [this] 를 사용 해 야 합 니 다. 예 를 들 어
int f();
struct s
{
int i;
void g()
{
    [this]{ this->i += f(); }();
}
};

위의 예 에서 i 에 대한 조작 은 this - > i 를 통 해 이 루어 진 것 이 므 로 i 조작 에 대해 직접 잘못 보고 할 수 있 습 니 다.
 
사실 c + + 0x 에 도 입 된 auto 는 lambda 와 잘 어 울 려 다음 코드 는 lambda 익명 대상 이 더 이상 익명 이 되 지 않도록 할 수 있 습 니 다.
auto hoo = []{};

사용 할 때 는 그냥 이렇게 하면 돼 요.
hoo();

일반 타 입 처럼 조작 하 다.
auto goo = new auto([]{});

 
아래 에 곰 이 출몰 하 니 조심스럽게 발 을 옮 겨 구경 하 세 요.
 
익명 lambda 대상 이 함수 부족 대상 일 때 어떤 외부 매개 변수 든 명시 적 전송 이 든 암시 적 전송 이 든 모두 잘못된 것 입 니 다.예 를 들 면
void f2()
{
  int i = 1;
  void g1(int = ([i]{ return i; })()); // ill-formed
  void g2(int = ([i]{ return 0; })()); // ill-formed
  void g3(int = ([=]{ return i; })()); // ill-formed
  void g4(int = ([=]{ return 0; })()); // OK
  void g5(int = ([]{ return sizeof(i); })()); // ill_formed
}

[this] 가 있 는 경 우 를 제외 하고 lambda 대상 이외 의 성명 을 사용 합 니 다. 생존 기간 이 있 는 변수 나 인용 은 합 법 적 이지 않 습 니 다. (use of a variable or reference with automatic storage duration declared outside the lambda - expression is ill - formed.)
void f1(int i)
{
  int const N = 20;
  [=]{
        int const M = 30;
        [=]{
             int x[N][M]; // OK: N and M are not "used"
             x[0][0] = i; // error: i is not declared in the immediately
             }; // enclosing lambda-expression
       };
}

좋은 웹페이지 즐겨찾기