C 11 Lambda 関数での型推論の制限
C 11 でラムダ関数と std::function を使用する場合、型推論ができない場合があります。期待どおりに実行されず、エラーが発生します。
問題
次の関数テンプレートを考えてみましょう:
template<class A> set<A> filter(const set<A>& input, function<bool(A)> compare);
この関数をラムダ関数で直接呼び出すと、たとえば:
filter(mySet, [](int i) { return i % 2 == 0; });
エラーが発生します。コンパイラがテンプレートの型を推論できないために発生します。 A.
説明
Lamda 関数は、匿名関数に便利な構文を提供する一方で、operator() メソッドを実装する個別の型です。これらは、正確な型を期待する型推定では直接サポートされていません。
解決策
この問題に対処するために、いくつかの回避策が存在します。
set<int> myNewSet = filter<int>(mySet, [](int i) { return i % 2 == 0; });
std::function<bool(int)> func = [](int i) { return i % 2 == 0; }; set<int> myNewSet = filter(mySet, func);
template<class A, class CompareFunction> set<A> filter(const set<A>& input, CompareFunction compare);
この変更されたテンプレートでは、CompareFunction 型は A 引数を受け取りブール値を返す関数オブジェクトを表します。テンプレート パラメーターは推測されなくなりましたが、明示的に指定されました。
追加機能
新しい decltype キーワードと関数の戻り値の型構文を使用すると、関数をさらに一般化して次のようにすることができます。戻り値の型を自動的に決定します:
template<class Value, class CompareType, class IndexType> auto filter(const set<Value>& input, CompareType compare, IndexType index) -> map<decltype(index(*(input.begin()))), Value> { ... }
このテンプレート関数は、入力設定値の型、比較の 3 つの型を想定しています。関数タイプとインデックス関数タイプ。戻り値の型は自動的に決定され、インスタンス化されます。
以上が関数テンプレートのラムダで C 11 の型推定が失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。