2011-08-17 3 views
24

:C++ 11 익명 함수 내에서 로컬 변수에 어떻게 액세스합니까? 나는 (I이 루프에 대한 꽤 사소한 실현)는 가능한 한 깨끗 코드를 만들기 위해 STL 알고리즘의 사용을 만들려고 노력, 벡터 (무게)에 간단한 정상화하고 있어요

float tot = std::accumulate(weights.begin(), weights.end(), 0.0); 
std::transform(weights.begin(), weights.end(), [](float x)->float{return(x/tot);}); 

현재, tot은 익명 함수에서 볼 수 없으므로 컴파일되지 않습니다. 익명 함수에 로컬 변수를 표시하는 가장 좋은 방법은 무엇입니까?

+0

죄송합니다. 0이어야합니다 0.0! 편집 됨 – bd1

답변

39

폐쇄가 필요합니다.

float tot = std::accumulate(weights.begin(), weights.end(), 0); 
std::transform(weights.begin(), weights.end(), [tot](float x)->float{return(x/tot);}); 

이 경우 tot은 값으로 캡처됩니다. 하여 C++ 11 람다지지 캡처 :

  1. [x]
  2. 참조 [&x]
  3. [&]
  4. 3과 동일하지만, 값 [=]

참조에 의한 현재 범위 내에서 임의의 변수 쉼표로 구분 된 목록 [x, &y]에 위 항목 중 하나를 섞을 수 있습니다. 암시 적 tot을 캡처

float tot = std::accumulate(weights.begin(), weights.end(), 0); 
std::transform(weights.begin(), weights.end(), [tot](float x)->float{return(x/tot);}); 

이 또는 당신이 캡처 기본을 사용할 수 있습니다 :

float tot = std::accumulate(weights.begin(), weights.end(), 0); 
std::transform(weights.begin(), weights.end(), [=](float x)->float{return(x/tot);}); 
+0

좋아요! STL에서 C++ 11 익명 함수 사용에 대한 좋은 웹/책 참고가 있습니까? 웹에서 발견 한 많은 것들이 익명 기능에 대한 구식 해결 방법이거나 임의의 블로그 게시물이었습니다. – bd1

+1

@ bd1 C++ 0x의 위키 피 디아는 실제로 꽤 좋습니다. 또한 대중에게 제공되는 마지막 표준 초안을 n3424라고합니다. 불행히도 C++ 0x에 대한 책은 아직 없습니다. – pmr

+0

'[=]'을 사용하여 클로저를 만들고 범위를 둘러싸고 변수를 복사하는 경우 전역 변수가 포함됩니까? 언제 사다리 위로 올라가는 걸 멈 춥니 까? –

2

당신은 "캡처 목록"에 tot를 추가해야 주변 범위 :

[ ..., N, ... ](int a, int b) -> int { return (a + b) * N; } 
^^^^^^^^^^^^^ ^^^^^^^^^^^^  ^^^^ 
captured vars local params  ret.type 

캡쳐 가능 값 또는 참조로 표시 할 수 있습니다. 특수 구문 [=][&]을 사용하여 주변 범위 (예 : 실제로 사용하는 모든 항목)에서 의 문자를으로 캡처 할 수 있습니다.

8

람다 수있다 "캡처"변수를

+0

람다를 함수 매개 변수로 파싱 할 경우 어떻게됩니까? 람다 함수가 매개 변수에 적합한 유형이 아니라는 오류가 발생합니다. – Acidic

+0

@Acidic : 람다 식의 * type *을 말할 수 없기 때문에 매개 변수가 클로저 유형 인 * functions *을 갖는 것은 매우 어렵습니다. 일반적으로 함수 * 템플릿 *을 사용하여 유형을 추론하거나 이기종 콜렉션 콜렉션을 관리해야하는 경우'std :: function'과 같은 유형 지우기 래퍼를 사용합니다. –