In einer Antwort auf diese SO-Frage:
Was ist das Äquivalent von boost::variant in der C++-Standardbibliothek?
es wird erwähnt, dass boost::variant
und std::variant
etwas abweichen.
- Was sind die Unterschiede für jemanden, der diese Klassen verwendet?
- Welche Motivation hat das Komitee zum Ausdruck gebracht?
std::variant
mit diesen Unterschieden?
- Was muss ich beim Codieren mit einem dieser beiden beachten, um die maximale Kompatibilität mit dem Wechsel zu dem anderen zu gewährleisten?
(die Motivation nutzt boost::variant
im Code vor C++17)
Es scheint der Hauptstreitpunkt bezüglich des Designs einer Variantenklasse gewesen zu sein, was passieren sollte, wenn eine Zuweisung an die Variante, die nach Abschluss den alten Wert zerstören sollte, eine Ausnahme auslöst:
variant<std::string, MyClassWithThrowingDefaultCtor> v = "ABC";
v = MyClassWithThrowingDefaultCtor();
Die Optionen scheinen zu sein:
- Verhindern Sie dies, indem Sie die möglichen darstellbaren Typen auf nichtthrow-move-konstruierbare beschränken.
- Behalten Sie den alten Wert bei – dies erfordert jedoch Doppelpuffer.
- Konstruieren Sie den neuen Wert auf dem Heap, speichern Sie einen Zeiger darauf in der Variante (damit die Variante selbst auch bei einer Ausnahme nicht verstümmelt wird). Das ist anscheinend was
boost::variant
tut.
- Verschaffen Sie sich für jede Variante einen ‘deaktivierten’ Zustand ohne Wert und gehen Sie bei solchen Fehlern in diesen Zustand über.
- Undefiniertes Verhalten
- Lassen Sie die Variante werfen, wenn Sie versuchen, ihren Wert zu lesen, nachdem so etwas passiert ist
und wenn ich mich nicht irre, wird letzteres akzeptiert.
Dies ist aus dem ISO C++-Blog zusammengefasst Post von Axel Naumann vom Nov 2015.
std::variant unterscheidet sich geringfügig von boost::variant
- std::variant wird in der Header-Datei deklariert und nicht in
- std::variant weist niemals Speicher zu
- std::variant ist verwendbar mit constexpr
- Anstatt boost::get(&variable) zu schreiben, müssen Sie std::get_if(&variable) für std::variant schreiben
- std::variant kann sich nicht rekursiv halten und verfehlt einige andere fortgeschrittene Techniken
- std::variant kann direkt Objekte konstruieren
- std::variant hat index() anstelle von which()
.
@JohnZwinck: Würde mich über Ihren Kommentar/Ihre Antwort freuen, wenn Sie sehen, wie Sie die von mir verlinkte Antwort geschrieben haben.
– einbinden
23. Okt ’16 um 9:20
Ich denke, JohnZwinck wird nicht benachrichtigt, es sei denn, er hat mit dieser Frage interagiert. Sie können stattdessen seine Antwort auf die andere Frage kommentieren, um seine Aufmerksamkeit zu erregen.
– DavidW
23. Okt ’16 um 9:43
Für diejenigen, die sich nicht bewusst sind,
boost::variant
undboost::variant2
sind zwei verschiedene Bibliotheken. Die Frage bezieht sich auf ersteres, aber es scheint erwähnenswert zu sein, dass die offizielle Dokumentation vonboost::variant2
gibt an, dass es API-kompatibel ist mitstd::variant
, mit einigen Vorbehalten: boost.org/doc/libs/1_75_0/libs/variant2/doc/html/… . Siehe auch die Boost-Projektliste unter boost.org/doc/libs/1_75_0– Max Barraclough
7. März ’21 um 18:23
@MaxBarraclough: Siehe Bearbeiten und auch diese neue Frage.
– einbinden
7. März ’21 um 23:42