2016-07-29 22 views
1

Ich habe folgende Funktionen:C++ Vorlage Argumentableitung schlägt mit Fehler "Kandidat Vorlage ignoriert" wenn Argumente gehören std :: function ... warum?

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; 
} 

Ich kann sie wie so nennen:

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

... und Verwendung Vorlage Argument Abzug mit Bar

double z = bar(1.0, 2.0); 

... aber wenn ich versuche, den Argumentabzug der Vorlage mit foo zu verwenden:

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

Es schlägt mit diesem Fehler:

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) 
     ^

Warum das so ist? Aus meiner Sicht ist es offensichtlich, woraus die Argumenttypen abgeleitet werden sollen.

Antwort

2

Die Typableitung berücksichtigt keine impliziten Konvertierungen, die später bei der Überladungsauflösung auftreten. Wenn Sie eine std :: -Funktion direkt übergeben würden, würde sie richtig abgeleitet werden. Es kann nicht implizit eine std::function von Ihrem Lambda ohne den Typ std::function konstruieren, um zu wissen, ob es möglich ist. Ich weiß, dass es aussieht, als gäbe es genügend Informationen für den Compiler, um die beteiligten Typen richtig abzuleiten, aber dies ist eine Einschränkung.

+0

Typabzug berücksichtigt nur * einige * implizite Konvertierungen. Nicht solche, bei denen Konstruktoren konvertiert werden. – Brian

+0

Es ist schade, dass das der Fall ist. Andernfalls wäre es möglich, eine Powerlogik ohne C++ 's typische Ausführlichkeit und Template-Shenanigans auszudrücken. – GuyGizmo