std::variant<>::emplace with index
-
Hallo
im einem anderen Thread hier hat camper mir einige Zeilen Code zur Verfügung gestellt.
(TwinCat Load Symbol Data @camper)Da der Thread mittlerweile mehrer Seiten umfasst und hier nicht mehr viele Leute reinschauen und dazu camper seit einiger Zeit nicht mehr verfügbar ist, stelle ich mal eine allgemeine Frage dazu hier in einem neuen thread.
Es wurde ein std::variant und ein enum wie folgt definiert.
struct Category { enum : std::size_t { base, alias, pointer, reference, array, class_ // class_ = struct, union, function block }; }; using SpecType = std::variant<std::monostate, DatatypeInfo*, // alias SubSymbolInfo, // pointer SubSymbolInfo, // reference ArrayInfo, // array std::vector<SubSymbolInfo>>;
an anderer Stelle wird nun mit hilfe von emplace ein Objekt dieses Variants erzeugt
und zwar so
SpecType typeSpecs; typeSpecs.emplace<Category::array>(dt, type);
Hier die Frage. Wieso wird der Typ ArrayInfo mit dem Index (4) aus dem enum erstellt
und nicht sotypeSpecs.emplace<ArrayInfo>(dt, type);
das wäre doch typsicherer.
a. Ist das die gängige Vorgehensweise?
b. Hat sich hier camper was anderes dabei gedacht, das nur aus dem Context hervorgeht den ich noch nicht überblickt habe?
-
Die Typ Variante funktioniert, wenn der gegebene Typ nur einmal im variant vorkommt (wie bei
tuple get
), daher wäre sie nicht allgemein anwendbar.I.A. würde ich versuchen, die Enumeration irgendwie automatisch generieren zu lassen. Bspw. habe ich für ein Compilerprojekt ein Makro namens
LABELLED_VARIANT
(link) geschrieben, das folgende Syntax ermöglicht:struct con : LABELLED_VARIANT( //(DATAcon, tuple<dataconstr, vector<tyc>, lvar>) (DATAcon, tuple<Symbol::symbol, lvar>) (INTcon, intType) (INT32con, std::int32_t) // …
Aber ja, der obige Code ist gängige Praxis.
-
Hi columbo.
das heißt es ist möglich einen Variant mit mehreren gleichen Typen zu definieren. Ja ok, möglich, aber was macht das für einen Sinn.
Wenn ich zum Beispiel folgendes mache. Dann kan meine Variant ein int sein oder auch ein int ??
std::variant<int, int>
-
@booster Ich verweise noch einmal auf meinen Compiler: https://github.com/Arcoth/SMLtoLLVM/blob/master/SMLNJInterface/PLambda.hpp
Alternativ hättest Du auch fragen können, warum funktionale Sprachen so etwas erlauben:
datatype Animal = Giraffe of int | Zebra of int
-
@C-olumbo
Das es möglich ist habe ich verstanden.
Aber dann sollte es ja auch egal sein wenn ich dann im oberen Fall den konkreten Typ angebe.
typeSpecs.emplace<ArrayInfo>(dt, type);
Wenn das ArrayInfo 2 mal im Variant vorkommt, würde es ja trotzdem korrekt funktionieren. Oder nicht?
-
@booster Streng doch mal die grauen Zellen an. Wenn jemand nach einem Zebra verlangt, wo eine Giraffe gegeben ist, weshalb sollte die Zahl aus der Giraffe zurückgegeben werden? Der Index ist eben Teil des Zustands, und wenn der Index ambig ist, ist die Abfrage ambig.
-
Um mal bei deinen Zootieren zu bleiben
Wenn ich so was mache wieusing Giraffe = int; using Zebra = int; std::variant<Giraffe, Zebra> animal;
dann kann ich doch auch mit
animal.emplace<Zebra>();
ein Zebra und keine Giraffe erzeugen obwohl beides die selben typen sind.