2015-10-07 18 views
30

Wann ist ein Lambda ein Garant für Trivialität, wenn überhaupt?Wann ist ein Lambda trivial?

Ich nahm an, dass, wenn es nur triviale Typen oder nichts erfasst, es trivial wäre. Ich habe jedoch keine Standardisierung, um das zu unterstützen.

Meine Motivation war es, etwas Code von Visual C++ 12 auf 14 zu verschieben und entdeckte einige statische Behauptungen, die beim Umgang mit Lambdas fehlschlugen, die ich für trivial hielt.

Beispiel:

#include <type_traits> 
#include <iostream> 
using namespace std; 

int main() 
{ 
    auto lambda = [](){}; 

    cout << boolalpha << is_trivially_copyable<decltype(lambda)>{} << endl; 
} 

Dies erzeugt false auf vs140 aber true in VS120 und Klirren. Ich konnte gcc nicht testen, da gcc> = 5 nicht vorhanden war. Ich gehe davon aus, dass dies eine Regression in vs140 ist, aber ich bin mir nicht sicher, ob das hier korrekt ist.

+4

gcc 5.2 produziert auch 'true': [Demo] (http://coliru.stacked-crooked.com/a/a7dc4ee4e32fb70a) – Jarod42

Antwort

30

Der Standard gibt nicht an, ob ein Verschlusstyp (der Typ eines Lambda-Ausdrucks) trivial ist oder nicht. Es überlässt dies explizit der Implementierung, wodurch es nicht portierbar ist. Ich fürchte, Sie können sich nicht darauf verlassen, dass Ihre static_assert etwas konsistentes produziert.

Zitiert C++ 14 (N4140) 5.1.2/3:

... Eine Implementierung kann den Verschluss anders definieren, was nachfolgend beschrieben bereitgestellt wird dies ändert nichts an der beobachtbaren Verhalten das Programm anders als durch Änderung:

  • die Größe und/oder Ausrichtung des Verschlusstypen,
  • ob der Verschluss trivially kopierbar ist (Ziffer 9),
  • ob der Verschlusstyp eine Standardlayout-Klasse (Klausel 9) ist, oder
  • , ob der Verschlusstyp eine POD-Klasse ist (Abschnitt 9).

...

(Hervorhebung von mir)

Nach der doppelten Negation in diesem Satz Parsing, können wir, ob der Verschlusstyp trivialen kopierbar sehen, dass die Implementierung erlaubt zu entscheiden ist, Standardlayout oder POD.

+0

Nun, das ist ziemlich traurig für mich :(Ich habe diese Antwort überhaupt nicht erwartet Ich glaube, ich habe eine Lektion gelernt, keine Annahmen zu machen. – tahsmith

13

Nach dem Entwurf des Standard N45275.1.2/3 Lambda-Ausdrücke [expr.prim.lambda] (Hervorhebung von mir):

Die Art des Lambda-Ausdruck (der auch Der Typ des Closure-Objekts) ist ein eindeutiger, unbenannter Nicht-Gruppenklassentyp, der Verschlusstyp genannt wird und dessen Eigenschaften im Folgenden beschrieben werden. Dieser Klassentyp ist weder ein Aggregat (8.5.1) noch ein Literaltyp (3.9). Der Abschluss Typ wird im kleinsten Blockbereich, Klassenbereich oder Namespacebereich deklariert, der den entsprechenden Lambda-Ausdruck enthält. [ Hinweis: Dies bestimmt die Menge der Namespaces und Klassen zugeordnet mit der Schließung Typ (3.4.2).Die Parametertypen eines Lambdadecla- rators haben keine Auswirkungen auf diese zugeordneten Namespaces und Klassen. - Endnote] Eine Implementierung kann die Schließung Typen anders definieren, was weiter unten beschrieben wird, sofern dies nicht ändert das beobachtbare Verhalten des Programms anders als durch eine Änderung:

(3,1) - die Größe und/oder Ausrichtung des Verschluss,

(3,2) - , ob der Verschluss trivially kopierbar ist (Ziffer 9),

(3,3) -, ob die Verschluss einer Standard-Layout-Klasse ist (Ziffer 9) oder

(3.4) - ob der Verschlusstyp ist eine POD-Klasse (Abschnitt 9).

Eine Implementierung wird nicht Mitglieder rvalue Referenztyp auf den Typ

So Schließung hinzuzufügen, es ist die Umsetzung abhängig.

Verwandte Themen