2017-12-13 3 views
1

C++ 입문서 5 판, 10 장 (람다 식)을 읽습니다. 벡터의 음수 값을 절대 값으로 대체하는 프로그램입니다. 람다가 void으로 반환 형식을 유추하지만 우리는이 문제를 해결하기 위해, 우리는 뒤에 반환 유형을 사용해야합니다 값을 반환하기 때문에if-else 문에 대한 λ 식의 반환 유형 공제

가이 코드는 컴파일되지 않습니다 :

transform(vi.begin(), vi.end(), vi.begin(), 
     [](int i) { if (i < 0) return -i; else return i; }); 

저자는 말한다 .

그러나이 코드를 Windows에서 GNU GCC 컴파일러로 컴파일하면 제대로 작동합니다. 그 유형이 조건 연산자의 유형에서 유추 할 수 있기 때문에 우리는 반환 형식, 를 지정하지 않아도 때문에

이 버전은 컴파일 :

저자는 말한다.

transform(vi.begin(), vi.end(), vi.begin(), 
      [](int i) { return i < 0 ? -i : i; }); 

그래서, 내 질문은 :

는 첫 번째 버전으로, 람다는 반환 무효가 입력 추론 왜
  • 가 왜 GNU GCC 컴파일러는 이것을 받아 들일 않습니다 * (나는 어쩌면 생각했다. 최적화 때문에).?
  • 왜 두 번째 버전에서 반환 유형을 조건부 연산자의 유형에서 추론 할 수 있습니까? lambda에서
+3

람다는 반환 된 표현식을 사용하여 반환 유형을 추론하므로 'return '에서 'void'를 추론 할 수 없습니다.이 책에는 오류가 있습니다. – Quentin

+1

'[] (int i) {if (i <0) return -i; 그렇지 않으면 i를 반환합니다. }'C++ 14에서는 완벽하게 괜찮습니다. – cpplearner

+4

이 책에 쓰여진 내용은 C++ 11에서는 사실 이었지만 C++ 14에서는 여러 개의 return 문을 사용할 수 있도록 개선되었습니다 (반환 된 형식이 일치하는 한). –

답변

3

:

... 폐쇄의 연산자의 반환 형식은() 다음과 같은 규칙 에 따라 결정됩니다

  • 몸이 아무것도하지만 구성하는 경우 표현식이있는 단일 return 문인 반환 유형은 반환 된 표현식 의 유형입니다 (값이 왼쪽에서 오른쪽, 배열에서 포인터 또는 함수에서 포인터로 바뀐 후 암시 적 변환); 그렇지 않으면 반환 유형이 void입니다.

  • (14 C++ 때까지) 반환 형식은 반환 문에서 도출되는 그 반환 타입 자동 선언되는 함수 에 대한 것처럼. (C++ 14 이후)

그래서 저자는 단지 C++ (14) 이후 C++ (14) 전 상황을 설명 코드는 완벽하게 작동합니다.

+0

고맙습니다. 저는 C++ 14 컴파일러를 사용하고 있습니다. 따라서 이것이 진짜 이유입니다. –