_variant_t in std::variant wandeln mit varadic template
-
Hallo
Versuche einen _variant_t (COM) in einen std::variant<...> zu wandeln
Dazu folgender Code
namespace { template <std::size_t N> struct variant_switch { template <typename Variant> void operator()(int index, _variant_t const &value, Variant &v) const { if (index == N) v = std::variant_alternative_t<N, Variant>(value); else variant_switch<N - 1>{}(index, value, v); } }; template <> struct variant_switch<0> { template <typename Variant> void operator()(int index, _variant_t const &value, Variant &v) const { if (index == 0) v = std::variant_alternative_t<0, Variant>(value); else throw std::runtime_error("while converting _variant_t to variant: invalid index"); } }; template <typename ...Args> struct converter<std::variant<Args...>> { static void from_variant_t(_variant_t const& vt, int index, std::variant<Args...>& v) { variant_switch<sizeof...(Args) - 1>{}(index, vt, v); } }; } _variant_t myvariant_t {5.0}; std::variant<int,float,double> myvariant; converter<decltype(myvariant)>::from_variant_t(myvariant_t, 2, myVariant);
Den ich von hier abgeschaut:
https://github.com/nlohmann/json/issues/1261 (hier wird von json in std::variant gewandelt)
und entsprechend angepasst habe. Zumindest versucht.Ich tu mir aber noch etwas schwer mit varadic templates.
Bei struct converter<std::variant<Args...>> erhalte ich den Fehler:
Error C2988 unrecognizable template declaration/definitionKann mir da jemand helfen?
-
Du hast die Deklaration des Primaertemplates
converter
vergessen:template <typename...> struct converter;
Abgesehen davon laesst sich das wahrscheinlich eleganter loesen. Kann man irgendwo die Definition von
_variant_t
einsehen?
-
Ohjee musste gerade feststellen dass ich ins falsche Unterforum gepostet habe. Wie konnte denn das passieren.
Sollte natürlich zu c++. Bitte verschieben.@columbo sagte in _variant_t in std::variant wandeln mit varadic template:
Du hast die Deklaration des Primaertemplates converter vergessen:
template <typename...>
struct converter;hier hast du nun einfach das Args im typename weg gelassen und den gesamten Ausdruck hinter converter?
Ok. Mal vorsichtig gefragt wieso?@columbo sagte in _variant_t in std::variant wandeln mit varadic template:
Kann man irgendwo die Definition von _variant_t einsehen?
Hilfe in der msdn
https://msdn.microsoft.com/de-de/library/ew0bcz27.aspxcode in comutil.h
z.b. hier
https://github.com/icestudent/vc-19-changes/blob/master/comutil.h
-
template <typename ...Args> struct converter<std::variant<Args...>>
ist ja eine Spezialisierung (obwohl es selbst wiederum ein Template ist).
Also muß es zuerst eine Deklaration des Grundtypsstruct converter
geben.
-
@th69 sagte in _variant_t in std::variant wandeln mit varadic template:
template <typename ...Args>
struct converter<std::variant<Args...>>ist ja eine Spezialisierung (obwohl es selbst wiederum ein Template ist).
Achso die Deklaration komm noch extra dazu, das ist keine Änderung des bestehenden Codes.
Der Teil fehlt aber auch bei der json Implementierung. Sehe ich das richtig?
-
@booster Nein, er fehlt nicht. In der JSON Implementierung ist die Deklaration des Primaertemplates eben auch eine Definition:
template <std::size_t N> struct variant_switch { ...
-
@Columbo: Wieso jetzt
variant_switch
? Bei der JSON-Implementierung geht es doch um den Typadl_serializer
, s.a. adl_serializer.hpp:template<typename, typename> struct adl_serializer
-
@th69 Ich bin einfach seinem Link vom OP gefolgt.
-
@columbo sagte in _variant_t in std::variant wandeln mit varadic template:
@booster Nein, er fehlt nicht. In der JSON Implementierung ist die Deklaration des Primaertemplates eben auch eine Definition
template <std::size_t N>
struct variant_switchhabe ich doch auch drin. Ich steh auf dem Schlauch.
mir gehts da wie Th69
adl_serializer habe ich in converter umbenannt. Die restlichen bezeichner habe ich belassen.
-
Ich auch, aber es geht ja um den 'variadic template'-Typ:
namespace nlohmann { template <typename ...Args> struct adl_serializer<std::variant<Args...>> { // ... } }
-
genau und diesen - adl_serializer - habe ich lediglich in converter umbenannt
Und in diesem json beispiel fehlt doch das
template <typename...> struct adl_serializer;
ebenfalls.
-
In dem Beispiel wird aber <nlohmann/json.hpp> eingebunden, welches wiederum dann <nlohmann/adl_serializer.hpp> einbindet.
-
-
Du hattes noch auf eine elegantere Lösung hingedeutet. Kannst du dazu noch was sagen?