2017-12-13 8 views
1

私はC++の初級5版、10章(ラムダ式)を読んでいます。ベクトルの負の値を絶対値で置き換えるプログラムです。if-else文のラムダ式の返り値の減算

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

著者がいることを言う:ラムダがvoidとして戻り値の型を推測するため

このコードはコンパイルされませんが、我々は値を返され、これを修正するために、我々は末尾の戻り値の型を使用する必要があります。 。

しかし、このコードをWindowsでGNU GCCコンパイラでコンパイルするとうまくいきます。そのタイプは、条件 オペレータの種類から推測することができますので、我々は戻り値の型、 を指定する必要はありませんので、

このバージョンでは、コンパイル:

作者もいるという。

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

だから、私の質問は以下の通りです。

  • 最初のバージョンで、ラムダは、戻り値の型がvoidとして推測し、なぜGNU GCCコンパイラはこれを受け入れないのはなぜ*(私は多分考えました最適化のため)。
  • なぜ2番目のバージョンでは、戻り値の型は条件付き演算子の型から推測できますか? lambdaから
+3

ラムダは返された式を使用して戻り値の型を推測するので、 'return 'から 'void'を推測することはできません。この本には誤りがあります。 – Quentin

+1

'[](int i){if(i <0)return -i;それ以外の場合はiを返します。 } 'はC++ 14では完璧です。 – cpplearner

+4

本書に書かれていることはC++ 11では当てはまりましたが、返された型が一致する限り、複数の 'return'文を許可するようにC++ 14で改善されました。 –

答えて

3

は...閉鎖のオペレータの戻り値の型は() 次の規則に従って決定されますボディは何で構成されている場合は

  • が、 式の1つのreturnステートメント、戻り値の型は返される式のタイプです (左辺値、配列へのポインタ、または関数ポインタへのポインタ 暗黙的変換)。それ以外の場合、戻り値の型はvoidです。

  • ( C++ 14まで)、戻り値の型は、その戻り型自動宣言された関数 ためかのようにreturn文から推定されます。 (C++ 14以降)

C++ 14のコードは完璧に動作しますので、そこで、著者はちょうど、C++ 14の前に状況を説明しています。

+0

ありがとう、私はC++ 14コンパイラを使用しています、それは本当の理由です。 –