>  기사  >  백엔드 개발  >  C++11의 새로운 기능인 람다 표현식에 대한 간략한 분석

C++11의 새로운 기능인 람다 표현식에 대한 간략한 분석

高洛峰
高洛峰원래의
2017-01-23 13:44:161505검색

람다 소개

파이썬에 익숙한 프로그래머라면 람다도 잘 알아야 합니다. 간단히 말해서, 람다는 익명으로 호출 가능한 코드 블록입니다. 새로운 C++11 표준에서 람다의 형식은 다음과 같습니다.

[capture list] (parameter list) -> return type { function body }

보시다시피 4개의 구성 요소가 있습니다.

1. 캡처 목록: 캡처 목록

2. 매개변수 목록: 매개변수 목록

3. 반환 유형: 반환 유형

4. 함수 본체: 실행 코드

이 중 매개변수 목록과 반환 유형은 무시할 수 있습니다.

몇 가지 간단한 예를 살펴보겠습니다.

auto f1 = [] { return 1; };
auto f2 = [] () { return 2; };
cout<<f1()<<&#39;\t&#39;<<f2()<<endl;

캡처 목록

람다의 캡처 목록은 값과 견적을 모두 캡처할 수 있습니다.

캡처 값:

int test_data[] = {1, 5, 9, 7, 3, 19, 13, 17};
int border = 8;
auto f3 = [border](const int &i){ if(i > border) cout<<i<<&#39;\t&#39;; };
for_each(begin(test_data), end(test_data), f3);
cout<<endl;

캡처 참조:

auto f4 = [&border](const int &i){ if(i > border) cout<<i<<&#39;\t&#39;; };
border = 6;
for_each(begin(test_data), end(test_data), f4);
cout<<endl;

출력에서 볼 수 있듯이 테두리가 작동합니다. 람다에서는 수정된 6으로 캡처가 실제로 참조임을 확인합니다.

참조를 캡처할 때 람다가 호출될 때 이 참조가 여전히 유효한지 확인해야 한다는 점에 유의해야 합니다.

캡처 목록은 암시적 캡처를 사용할 수도 있습니다. 이를 통해 컴파일러는 람다 실행 코드를 통해 캡처해야 하는 지역 변수를 결정할 수 있습니다.

암시적 캡처는 값, 참조 또는 이 둘의 혼합을 캡처할 수 있습니다.

char space = &#39; &#39;;
auto f5 = [=](const int &i){ if(i > border) cout<<i<<&#39;\t&#39;; };
auto f6 = [&](const int &i){ if(i > border) cout<<i<<&#39;\t&#39;; };
auto f7 = [&, space](const int &i){ if(i > border) cout<<i<<space; };
border = 0;
for_each(begin(test_data), end(test_data), f5);
cout<<endl;
for_each(begin(test_data), end(test_data), f6);
cout<<endl;
for_each(begin(test_data), end(test_data), f7);
cout<<endl;

여기에서 f7이 사용하는 혼합 형식은 "공간에 추가"로 읽을 수 있습니다. 값을 캡처하고 다른 변수는 참조를 캡처합니다."

변수 람다

람다가 값에 의해 캡처된 변수의 값을 수정해야 하는 경우 가변 키워드를 람다에 추가해야 합니다. 그렇지 않으면 컴파일 오류가 발생합니다.

auto f8 = [&, space](const int &i) mutable { if(i > border) {cout<<i<<space; space=&#39;\t&#39;;} };
for_each(begin(test_data), end(test_data), f8);
cout<<endl;
cout<<1<<space<<2<<endl;

출력에서 볼 수 있듯이 첫 번째 호출 후 람다 f8의 공백 값은 탭 문자 Tab으로 바뀌었지만 람다 외부에는 여전히 공백이 있습니다. 공간.

반환형

람다의 반환형은 tail return형 방식을 채택하고 있다. 일반:

1. 람다에 return 문만 포함된 경우 컴파일러는 반환 유형을 추론할 수 있으며 반환 유형을 명시적으로 지정할 필요가 없습니다.

2. 그렇지 않으면 compile 컴파일러는 람다가 void를 반환하고 void를 반환하는 함수는 특정 값을 반환할 수 없다고 가정합니다. 이는 대부분의 경우 모순이므로 반환 유형을 명시적으로 지정해야 합니다.

그러나 실제 테스트 후에는 현재 g++ 컴파일러가 더 똑똑해졌습니다. 포인트 2의 경우 컴파일러가 람다 함수 본문에서 함수의 반환 유형을 추론할 수 있는 한, 그럴 필요가 없습니다. 공식은 반환 유형을 명시적으로 지정합니다. 예:

auto f9 = [](const int i){if(i % 3) return i * 3; else return i;};
transform(begin(test_data), end(test_data), begin(test_data), f9);
border = 0;
for_each(begin(test_data), end(test_data), f6);
cout<<endl;

람다 코드 블록에는 여러 개의 반환 문이 있고 if/else 문도 있지만 컴파일러는 다음을 기반으로 추론할 수 있습니다. 반환하는 return 문 값은 int 유형이어야 하므로 후행 반환 유형을 생략할 수 있습니다.

단, 다음 형식에서는 컴파일러가 반환 유형을 유추할 때 불일치를 발견하므로 반환 유형을 명시적으로 지정해야 합니다.

auto f10 = [](const int i) -> double
{if(i % 5) return i * 5.0; else return i;};
transform(begin(test_data), end(test_data), begin(test_data), f10);
for_each(begin(test_data), end(test_data), f6);
cout<<endl;

요약

1. 람다 표현식 형식: [캡처 목록] (매개변수 목록) -> 반환 유형 { 함수 본문 }, 여기서 매개변수 목록과 반환 유형은 생략 가능합니다.

2. 캡처 목록은 값 [val] 또는 참조 [&ref]를 캡처할 수 있습니다.

3. 캡처 목록은 로컬 변수를 암시적으로 캡처할 수도 있습니다. 또한 값 캡처[=]와 참조 캡처[&]의 두 가지 방법을 혼합할 수도 있습니다. [&, val] 또는 [=, &ref]를 캡처합니다.

4. 람다가 캡처한 값을 수정해야 하는 경우 mutable 키워드를 추가해야 합니다.

4. 람다가 반환 값 유형을 자동으로 유추할 수 없는 경우 반환 유형을 뒤에 명시적으로 지정해야 합니다.

위 내용은 C++11의 새로운 기능인 람다 표현식의 전체 내용입니다. 이 글이 C++를 배우는 모든 분들께 도움이 되었으면 좋겠습니다.

C++11의 새로운 기능을 간략하게 분석한 람다 표현식과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.