webentwicklung-frage-antwort-db.com.de

Wo std :: variant over union verwenden?

Bitte erläutern Sie den Unterschied zwischen union und std::variant und warum std::variant wurde in den Standard eingeführt? In welchen Situationen sollten wir std::variant über der alten Schule union?

43
user7466998

Im Allgemeinen sollten Sie variant bevorzugen, es sei denn, eine der folgenden Bedingungen wird erfüllt:

  1. Du betrügst. Sie tun Typ-Punning oder andere Dinge, die UB sind, aber Sie hoffen, dass Ihr Compiler Ihren Code nicht kaputt macht.

  2. Sie führen einige der Pseudopunnerys aus, die C++ unions ausführen dürfen: Konvertierung zwischen layoutkompatiblen Typen oder zwischen allgemeinen Anfangssequenzen.

  3. Sie benötigen ausdrücklich unbedeutende Kopierbarkeit und/oder Layoutkompatibilität. variant<Ts> müssen nicht über ein bestimmtes Layout oder eine unbedeutende Kopierbarkeit verfügen. unions von Standardlayouttypen sind Standardlayout, und unions von trivial kopierbaren Typen sind trivial kopierbar.

    Beachten Sie, dass es einen Vorschlag gibt, variant trivial kopierbar zu machen, wenn seine Komponententypen trivial kopierbar sind . Es wird als Fehlerbericht für C++ 17 vorgeschlagen, sodass dieses Verhalten effektiv in C++ 17 zurückportiert wird.

  4. Sie benötigen Unterstützung auf niedriger Ebene für das direkte Schalten von Objekten. Die Verwendung eines Speicherpuffers für solche Dinge bietet nicht die triviale Garantie, dass Sie aus einem union herauskommen könnten.

Der grundlegende Unterschied zwischen den beiden besteht darin, dass variant weiß , welchen Typ er speichert, während union erwartet, dass Sie den Überblick behalten davon extern. Wenn Sie also versuchen, auf das falsche Element in einem variant zuzugreifen, erhalten Sie eine Ausnahme oder nullptr. Im Gegensatz dazu ist dies mit einem union nur undefiniertes Verhalten.

union ist ein untergeordnetes Tool und sollte daher nur verwendet werden, wenn Sie dieses untergeordnete Tool unbedingt benötigen.

variant hat auch Maschinen für Besuche, was bedeutet, dass Sie vermeiden müssen, eine Reihe von if Anweisungen zu haben, bei denen Sie fragen, ob es sich um Typ X handelt. Wenn es sich um Typ Y handelt, tun Sie dies das, etc ".

65
Nicol Bolas