#include <iostream>
int main(){
auto lambda = [] {
return 7;
};
std::cout << lambda() << '\n';
}
このプログラムはコンパイルして7を出力します。
ラムダの戻り値の型は、戻り値7に基づいて整数型に推定されます。
通常の関数でこれができないのはなぜですか?
#include <iostream>
auto function(){
return 42;
}
int main(){
std::cout << function() << '\n';
}
エラー: ‘関数’関数は、末尾の戻り値型なしで「自動」型指定子を使用します
C++ 14にはこの機能があります 。 -std=c++1y
フラグを設定すると、GCCまたはclangの新しいバージョンでテストできます。
それに加えて、C++ 14では、関数にdecltype(auto)
(変数のdecltype(auto)
を反映)を使用して、decltype
セマンティクスを使用して戻り値を推定することもできます。 。
例は、decltype(auto)
が特に役立つ転送機能の場合です。
template<typename function_type, typename... arg_types>
decltype(auto) do_nothing_but_forward(function_type func, arg_types&&... args) {
return func(std::forward<arg_types>(args)...);
}
decltype(auto)
を使用すると、指定した引数で呼び出されたときに、func
の実際の戻り値の型を模倣します。 C++ 11では非常にイライラし、エラーが発生しやすい、末尾の戻り値型のコードの重複はなくなりました。
これは、言語がどのように作成され、進化したかの制限にすぎません。今後のC++ 14標準では、関数の戻り値の型は、すべてではありませんが、一部のコンテキストで推定できます。複数のreturnステートメントがある場合、複雑になります。
さらに、推定される戻り値の型には他の問題があります。たとえば、テンプレート関数の戻り値の型は [〜#〜] sfinae [〜#〜] コンテキストでは使用できないため、推定できますタイプ、コンパイラは関数テンプレートをインスタンス化する必要があります。これはafter置換の後に行われます。最終的には、この機能は近い将来に存在することになりますが、自分でタイプを提供できる場合は、それを避けます。
これはc ++ 14で提供されます。次の proposal を参照してください。
まだそこにはありません。C++ 1y/C++ 14に含まれる予定です。これをチェックしてください 機能のリンク
私の推測では、それはおそらく型推論されたラムダは再帰的ではないが原因です。
なぜこれが問題なのですか?型推論されたラムダが再帰的である可能性がある場合(「型推論」とは、変数の名前がauto
型である場合を意味します)、その戻り値の型は、それ自体に依存する可能性があります。解決することは可能ですが、「単純な」型推論よりも実装がはるかに困難です。それがalways解決可能であるかどうかさえわかりません(一般的なケースでは決定可能ですか?)。ただし、関数が型推論をサポートしている場合は、この問題に対処する必要があるため、この理由で除外された可能性があります。