2016-07-29 8 views
1

私は次のような機能を持っている:私はそうのようにそれらを呼び出すことができます引数にstd :: function ...が含まれていると、C++のテンプレート引数の控除が失敗して "候補テンプレートが無視されました"というエラーが表示されます。

template <class InType, class OutType> 
OutType foo(const InType &a, std::function<OutType (const InType &)> func) 
{ 
    return func(a); 
} 

template <class T> 
T bar(T a, T b) 
{ 
    return a + b; 
} 

double x = foo<int, double>(1, [] (const int &v) { return float(v) * 1.5f; }); 
double y = bar<int>(1.0, 2.0); 

...とバー

double z = bar(1.0, 2.0); 

とテンプレート引数控除を使用...しかし、 fooでテンプレート引数の控除を使用しようとすると:

double w = foo(1, [] (const int &v) { return float(v) * 1.5f; }); 

それは、このエラーで失敗します。

no matching function for call to 'foo' 
    double w = foo(1, [] (const int &v) { return float(v) * 1.5f; }); 
       ^~~ 
note: candidate template ignored: could not match 'function<type-parameter-0-1 (const type-parameter-0-0 &)>' against '(lambda at ../path/to/file.cpp:x:y)' 
OutType foo(const InType &a, std::function<OutType (const InType &)> func) 
     ^

それはなぜですか?私の立場からすれば、引数の型を推測するのは明らかです。

答えて

2

タイプ控除では暗黙の変換は考慮されません。これは後で過負荷解決時に発生します。あなたがstd ::関数を直接渡す場合、それは適切に推論するでしょう。あなたのラムダからstd::functionを暗黙的に構築することは可能であるかどうかを知るためにstd::functionのタイプを指定することはできません。コンパイラが関係する型を適切に推論するのに十分な情報があるように見えますが、これは制約です。

+0

タイプ控除は、*いくつかの暗黙的な変換のみを考慮します。コンストラクタの変換を伴うものではありません。 – Brian

+0

これはあまりにも悪いことです。さもなければ、C++の典型的な冗長性やテンプレートの偽りのないパワーロジックを表現することができます。 – GuyGizmo

関連する問題