Wie kann ich Lambda-Ausdruck als Parameter an C ++ - Vorlage übergeben

8

Ich habe eine Vorlage, die eine Funktion als Argument akzeptiert.

Wenn ich versuche, einen Lambda-Ausdruck zu übergeben, kompiliert er nicht.

%Vor%

Was ich vermisse?

    
gsf 27.04.2016, 05:09
quelle

4 Antworten

11

Ein Lambda ist kein Funktionszeiger! Ein Lambda ist eine Instanz der vom Compiler erzeugten Klasse!

Jedoch kann ein nicht erfassendes Lambda mit seiner operator+

in einen Funktionszeiger umgewandelt werden

Hier ist ein Beispiel:

%Vor%

Leider funktioniert das operator+ in Ihrem Fall nicht einmal, weil es nicht als consExpr deklariert wurde, Sie können es also nicht in einem Template-Parameter verwenden.

Eine Lösung für Ihren Fall wäre die Verwendung einer kostenlosen Funktion ... bis N4487 nicht akzeptiert wird, Sie können nicht erwarten, Lambda als Vorlageparameter zu übergeben.

Eine andere Lösung wäre, einen eigenen Funktor anstelle eines Lambda zu erstellen:

%Vor%

Diese Lösung ist nicht sehr ansprechend, aber es könnte nützlich sein, wenn LambdaType in einer cpp-Datei versteckt ist.

Wenn Ihr Ziel nur der Compiler ist, um Ihren Code in Zeilen zu fassen, können Sie Vorlagen verwenden, um das Lambda herumzugeben:

%Vor%

Da der Compiler den Typ von T für jede Instanz kennt, sollte ein guter Compiler das Lambda optimieren können.

Mit clang gibt die dritte Option die folgende Assembly:

%Vor%

Ich habe -std=c++14 -Ofast -march=native als Flags verwendet.

    
Guillaume Racicot 27.04.2016, 05:36
quelle
6

Dies liegt daran, dass das Lambda ein eigener Typ ist.
Sie haben templaize function() für den Typ der übergebenen Funktion.

%Vor%     
Martin York 27.04.2016 05:48
quelle
2

Ich weiß nicht genug von dem Standard, um zu sagen, ob dies mein Compiler-Fehler ist, der es nicht richtig implementiert, oder wenn es eigentlich der Standard ist, aber mit VS2015 kann man keinen Konstanten-Lambda-Ausdruck zur Kompilierungszeit erzeugen. Und Vorlagen nehmen nur Kompilierzeitkonstanten, also keine Lambdas.

Sie müssen jedoch nicht als Vorlage verwenden, wenn Sie ein Lambda übergeben möchten. Es ist vollkommen möglich ohne:

%Vor%     
nvoigt 27.04.2016 05:32
quelle
1

Dies liegt nur daran, dass "Sie den Namen oder die Adresse einer lokalen Variablen nicht als Vorlagenargument verwenden können". Wenn Sie ein globales statisches Lambda erstellen möchten, gehen Sie auf Ссылка Sie können finden, was Sie wollen.

    
Gran 27.04.2016 05:55
quelle

Tags und Links