[functional]std::function<> kann Funktionssignatur nicht deduzieren



  • Hallo,

    Die Methode kann auf mysteriöse Weise nicht den Typ deduzieren und der Compiler meckert, die Signatur des Callbacks würde nicht übereinstimmen, dabei kann ich nur raten warum.

    
    struct base {};
    struct derived : base {};
    
    #include <functional>
    #include <type_traits>
    
    template<typename T, typename std::enable_if<std::is_base_of<base, T>::value>::type* = nullptr>
    void add(T& , std::function<void(T&)>&& = std::function<void(T&)>{}) {}
    
    int main(){
        derived d;
        add(d, [](derived& ){}); // funktioniert nicht
        add<derived>(d, [](derived& ){}); // funktioniert
    }
    

    Spuckt mir den folgenden Fehler aus:

    file: In function ‘int main()’:
    file:229:27: error: no matching function for call to ‘add(derived&, main()::<lambda(derived&)>)’
         add(d, [](derived& ){}); // funktioniert nicht
                               ^
    file:225:6: note: candidate: ‘template<class T, typename std::enable_if<std::is_base_of<base, T>::value>::type* <anonymous> > void add(T&, std::function<void(T&)>&&)’
     void add(T& , std::function<void(T&)>&& = std::function<void(T&)>{}) {}
          ^~~
    file:225:6: note:   template argument deduction/substitution failed:
    file:229:27: note:   ‘main()::<lambda(derived&)>’ is not derived from ‘std::function<void(T&)>’
         add(d, [](derived& ){}); // funktioniert nicht
                               ^
    make: *** [Makefile:966: test.o] Error 1
    

    Was hab ich falsch gemacht? Funktioniert mit beiden Compilern nicht (clang, g++).



  • Da


  • Mod

    Ein Template-Parameter P, der als Template-Argument in einer template-id vorkommt, also T<P>, kann in der Regel nur deduziert werden, wenn ein Ausdruck vom Typ T<X> gegeben ist.

    Überleg mal, was hier verglichen wird: function<P> und ein Ausdruck von irgendeinem closure Typ, der keinerlei Verbindung zu function hat. Wenn wir so etwas unterstützen wollten, müssten wir die Parameterliste des closure operator() inspizieren, was wiederum zu komplexeren Regeln führt, und im Falle von polymorphen Lambdas nicht funktioniert.



  • Stimmt, war schon bisschen spät 🙂
    Danke jedenfalls


Anmelden zum Antworten