C 11 の std::function と Lambda 関数を使用した型推定
C 11 でテンプレートを使用する場合、型推定は強力な機能。ただし、型推論が失敗する特定のシナリオ、特に std::function または lambda 関数が関係する場合があります。
次の例では、関数テストは型 A のセットを受け入れ、明示的に指定せずに同じセットを返します。テンプレート タイプの指定:
template<class A> set<A> test(const set<A>& input) { return input; }
コード内の他の場所で test(mySet) を使用してこの関数を呼び出すと、期待どおりに機能します。ただし、関数をラムダ関数とともに使用すると、型推論が失敗します:
template<class A> set<A> filter(const set<A>& input,function<bool(A)> compare) { // ... implementation }
filter(mySet,[](int i) { return i%2==0; }) でフィルターを呼び出そうとしています。 ;エラーが発生します:
error: no matching function for call to ‘filter(std::set&, main()::)’
この問題は、ラムダが関数または std::function オブジェクトではないために発生します。これらは、標準によって定義された特定のプロパティを持つ関数オブジェクトです。型推定は正確な型でのみ機能し、ラムダはこの基準を満たしません。
これを解決するには、ラムダを std::function に変換するか、テンプレートの型を明示的に指定します。
// Convert lambda to std::function std::function<bool(int)> func = [](int i) { return i%2 ==0; }; set<int> myNewSet = filter(mySet,func); // Provide template type explicitly set<int> myNewSet = filter<int>(mySet,[](int i) { return i%2==0; });
あるいは、関数を再定義して、 CompareFunction:
template<class A,class CompareFunction> set<A> filter(const set<A>& input,CompareFunction compare) { // ... implementation }
この変更により、テンプレートの型を指定せずに関数を呼び出すことができます:
set<int> result = filter(myIntSet,[](int i) { i % 2 == 0; });
複数引数ラムダでは型推論にも問題が生じる可能性があります。このような場合、auto を使用すると便利な解決策となります:
template<class Value,class CompareType,class IndexType> auto filter(const set<Value>& input,CompareType compare,IndexType index) -> map<decltype(index(*(input.begin()))),Value> { // ... implementation }
この関数は次のように呼び出すことができます:
map<string,int> s = filter(myIntSet,[](int i) { return i%2==0; },[](int i) { return toString(i); });
以上がC 11 の std::function と Lambda 関数で型推定が失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。