alles erfassen vs. nur einige in einem Lambda erfassen

8

Ab und zu komme ich mit Code wie folgt auf:

%Vor%

Ich würde gerne wissen, welche der lambdas in Bezug auf Leistung und vielleicht ausführbare Größe nach dem C ++ 14 Standard (oder später) und Ihrer praktischen Erfahrung mit Compilern besser ist.

    
user1095108 30.11.2015, 13:23
quelle

3 Antworten

3

Wenn Sie den trivialen Fall ausschließen, in dem Sie explizit etwas erfassen, das nicht in Lambda erwähnt wird, gibt es zwei Fälle, in denen es Unterschiede geben kann.

Erstens erfassen implizite Erfassungen im Allgemeinen keine Entitäten, die nicht odr-used sind (siehe jedoch den nächsten Eintrag für die Ausnahme dazu). Dies schließt unter anderem Dinge ein, die in nicht bewerteten Operanden wie denen von decltype und sizeof sowie bestimmten lokalen Variablen const und constexpr erwähnt werden, wenn sie in bestimmten Kontexten verwendet werden (siehe [basic.def.odr] für das vollständige Regelwerk):

%Vor%

Wenn Sie die Aufnahmeliste manuell schreiben, ist es möglich, dass Sie mehr aufnehmen, als Sie technisch benötigen, da die Regeln, die bestimmen, was odr-verwendet wird oder nicht, ziemlich komplex sind.

Zweitens erfassen implizite Captures in generischen Lambdas Dinge, die in einem abhängigen Ausdruck verwendet werden, auch wenn sie aus Gründen der Gesundheit nicht notwendigerweise odr verwendet werden. Ausleihen ein Beispiel aus dem Standard :

%Vor%

Allerdings ist es nicht unbedingt erforderlich, etwas zu erfassen, das beim Schreiben eines generischen Lambda verwendet werden darf oder nicht; Sie müssen es nur erfassen, wenn Sie eine Spezialisierung des Funktionsaufrufoperators instanziieren, der die Sache verwendet. Wenn Sie also das resultierende generische Lambda niemals auf eine Weise aufrufen, die das fragliche Objekt odr-verwenden würde, könnte die implizite Erfassung mehr als das Minimum erfassen, das Sie benötigen. Zum Beispiel ist dies erlaubt:

%Vor%

solange Sie g3 nicht mit einem Objekt der Größe 1 aufrufen: g3(0) ist auf typischen Systemen OK; g3('%code%') ist nicht.

    
T.C. 01.12.2015, 02:14
quelle
5

In diesem Beispiel gibt es keinen Unterschied. Der Compiler wird nur Variablen erfassen, auf die im Lambda explizit Bezug genommen wird, sodass das verzögerte Erfassen dem expliziten entspricht.

Eine faule Aufnahme ist etwas bequemer. Das Ändern des Körpers von Lambda, um zusätzliche erfasste Variablen zu verwenden, oder das Entfernen aller Verweise auf eine erfasste Variable von einem vorhandenen Lambda, würde normalerweise auch das Aktualisieren einer expliziten Erfassungsliste erfordern. Mit einer Lazy Capture wird der Compiler alles für Sie tun.

    
Sam Varshavchik 30.11.2015 13:41
quelle
1

Wie oben erwähnt, gibt es keinen Unterschied in Bezug auf den generierten Code. Ich glaube jedoch, dass es besser ist, explizit zu sein - es gibt bessere Lesbarkeit (leichter über den variablen Lebenszyklus zu denken) und gibt Ihnen bessere Unterstützung vom Compiler, was zu Fehlern führt, wenn Sie auf die Variable zugreifen, die Sie nicht wollten / p>

Ich glaube, dass 'faules Capturen' überhaupt kein gutes Feature ist.

    
SergeyA 30.11.2015 14:28
quelle

Tags und Links