Betrachten Sie diese einfache (schlechte) Funktionsvorlage, für die auf dieser Site viele Variationen existieren:
%Vor%Und zwei Versuche, es aufzurufen:
%Vor% Ich kann (a)
nicht aufrufen, weil ein Lambda kein std::function<R(Args...)>
ist, so dass der Vorlagenabzug fehlschlägt. Einfach.
Allerdings schlägt auch (b)
fehl. Ich vermute, das liegt daran, dass der Compiler nicht bestimmen kann, dass ich die Artargumente und Gründe, die ich einfach R
zur Verfügung stelle, all liefern soll, also versucht (und scheitert), Args...
für abzuleiten Aus demselben Grund, dass der erste Anruf fehlgeschlagen ist.
Gibt es eine Möglichkeit, explizit anzugeben, dass ich all die Vorlagenargumente zur Verfügung stelle? Zur Klarstellung bin ich daran interessiert, only die Template-Argumente explizit anzugeben, damit es keinen Template-Abzug gibt - ich suche nicht nach dem richtigen Weg, um call_with
zu schreiben oder um eine Vorlage zu erstellen Abzug gelingt, wenn mit einem Lambda aufgerufen wird.
Die kurze Antwort auf Ihre - bearbeitete - Frage lautet: Wenn Sie die Deklaration von call_with()
nicht ändern können, verwenden Sie entweder die von @CoffeeandCode gezeigten Typumwandlungen oder verwenden Sie die unten beschriebene Technik, um einen Wrapper für% zu erstellen. co_de%.
Das Problem liegt darin, dass der Compiler versucht, die Template-Argumente vom ersten Funktionsargument abzuleiten. Sie können dies verhindern, wenn Sie Ihren Code wie dies schreiben:
%Vor%Wenn eine Template-Metafunktion zum Generieren des std :: -Funktionstyps verwendet wird, kann der Compiler nicht einmal versuchen, den Funktionstyp vom ersten Argument abzuleiten, und er wird nur die anderen Argumente verwenden.
Sie müssten natürlich immer noch den Rückgabetyp angeben, aber für die anderen Argumente können Sie jetzt wählen, ob Sie sie explizit angeben oder es dem Compiler überlassen, sie aus den angegebenen Argumenten abzuleiten.
Wenn Sie wirklich erzwingen möchten, dass alle Vorlagenargumente bereitgestellt und nicht abgeleitet werden, können Sie das Argumentpack auch in einen Aufruf von call_with()
auf diese Weise einfügen:
Wenn Sie also verhindern möchten, dass der Compiler Argumenttypen von Funktionsvorlagen ableitet, die auch als Funktionsparameter angezeigt werden, müssen Sie sie in eine Metafunktion wie identity
einfügen.
Sie können den Funktionstyp vorher wie folgt angeben:
%Vor%oder etwas unordentlicher, aber kompakter:
%Vor% Dies liegt daran, dass der Compiler den Rückgabetyp und die Argumente für Ihre Template-Parameter nicht erkennt, bevor Sie ihn auffordern, ein vom Compiler definiertes Lambda, also ein nicht spezifiziertes Funktionsobjekt, implizit in ein std::function
mit zu konvertieren diese Vorlagenparameter.
Wirklich, du solltest nur deine Funktion warpper ändern, um allgemeiner zu sein:
%Vor%Dies sollte für jede Funktion oder jeden Funktortyp funktionieren. Es ist auch ein wirklich gutes Beispiel für die Verwendung von Trailing-Return-Typen.
Tags und Links c++ c++11 templates template-deduction