Ich hatte eine Funktion submitAsync
, die ein Template std::function
als Parameter akzeptiert:
Die implizite Vorlagenargumentableitung funktionierte jedoch nicht, wenn ein Lambda übergeben wurde (ähnlich dem Problem hier , also musste ich eine generische Funktion erstellen, die die Funktion als Template-Parameter akzeptiert, um sie dann an die ursprüngliche Funktion zu übergeben:
%Vor%Dies wird mit Clang in Ordnung gebracht, aber mit GCC wird der folgende Fehler zurückgegeben:
%Vor%Dies zeigt zum einen, dass die Zeilen
sind %Vor% was submitAsync(const function<Ret (Args...)> &, Args&&...)
aufrufen sollte, versucht tatsächlich, submitAsync(Func &&func, Args&&... args)
aufzurufen, was natürlich nicht funktioniert, da der Typ von func
, der übergeben wird, int
ist.
Der letzte Teil des Fehlers verstehe ich auch nicht, expansion pattern ‘#‘nontype_argument_pack’ not supported by dump_expr#<expression error>’ contains no argument packs
, was vielleicht ein Compiler Bug sein könnte (Zeile 82 ist der Hauptteil der Signatur der Funktion, wo ich einen Kommentar setze um es zu markieren)?
Seltsamerweise, wenn ich die expliziten Template-Parameter im Aufruf von submitAsync
lösche, ersetze diese Zeile:
mit diesem:
%Vor%GCC kompiliert es korrekt. Also, warum ruft GCC die falsche Funktion auf, wenn die Template-Argumente angegeben werden, obwohl es funktioniert, wenn es erlaubt ist, die Argumente abzuleiten? Und kann mir jemand sagen, was der seltsame Fehler in Zeile 82 ist?
Bearbeiten: Vergessen zu erwähnen, ich benutze GCC 4.7.2
EDIT 2: Lösung und Erklärung hier
Nach weiteren Tests habe ich festgestellt, dass sowohl Clang als auch GCC ohne explizite Template-Parameter nicht so funktionierten, wie ich es wollte. In beiden Fällen hat sich die Funktion nur selbst als die erste Funktion bezeichnet, die zu den Parametern passt. Es wurde dadurch verursacht, dass der Compiler entschieden hat, dass submitAsync
, das die Funktion als Template-Parameter akzeptiert, eine bessere Übereinstimmung hat als die, die ein const std::function&
verwendet. Es funktioniert jetzt gut, nachdem Sie submitAsync
geändert haben, um die Funktion als Referenz zu verwenden: