std::variant an anderen std::variant zuweisen wenn unterliegender Typ gleich.



  • Hallo zusammen. Erst mal Code. 🙂

    class MyClass
    {
    public:
        using   myvariant = std:variant<bool, int, float, Double>
        virtual ~MyClass = 0 // klasse ist abstract
    
    
        template <typename  Tvalue>
        Tvalue GetValue() const
        {        
            return std::get<Tvalue>(Value);
        }
    
        template <typename  Tvalue>
        void SetValue(const Tvalue value)
        {
            Value = value;
        }
    
    protected:
        myVariant value;
    }
    
    template<typename Tvalue>
    class MyClass_T
    {
    public:    
        Tvalue GetValue() const
        {
             return base::GetValue<Tvalue>();
        }
        
        void SetValue(const Tvalue value)
        {
               Value = value;
        }
    }
    

    Habe ne Basisklasse ohne Template und eine davon abgeleitete Klasse mit Template.
    Ich speichere den "Value" in einem std::variant in der Basisklasse, da ich in einem std::vector Zeiger auf die Basisklasse halte. Und beim iterieren aber Zugriff auf den "Value" benötige.

    Nun erhalte ich nen std::variant von einer Methode als Rückgabe und würde diesen gerne zuweisen aber nur wenn
    der variant den ich zuweisen will auch dem variant entspricht der im konkretten objekt hinterlegt ist auf das der Zeiger verweist.

    auto value = GetVaraiant();
    ptrbase->SetValue(value); // Fehler zur Compilezeit geht ja nicht. Aber eventuell zur Laufzeit?
    

    hoffe meine Ausführung ist verständlich.



  • Was willst Du überhaupt machen? Dann nimm doch einfach std::any, wenn du dich nicht auf 4 Typen beschränken willst. Das klingt irgendwie nach Design-Fehler (oder ich hab das Problem nicht verstanden). Aber spontan würde ich sagen für die 4 Tvalue's spezialisieren und sonst nichts machen (was das bringen soll, keine Ahnung).



  • Schlechtes Minimalbeispiel...hier wird nichts abgeleitet, was ist 'base::', was ist 'GetVaraiant()'..?
    Sofern ich das trotzdem richtig verstehe, kannst du im setter zur Laufzeit mit typeid gucken, ob die Typen gleich sind.



  • Hallo.

    Ja ihr habt recht mein Beispiel ist nicht vollständig. Entschuldigung.

    @Jockelx sagte in std::variant an anderen std::variant zuweisen wenn unterliegender Typ gleich.:

    Sofern ich das trotzdem richtig verstehe, kannst du im setter zur Laufzeit mit typeid gucken, ob die Typen gleich sind.

    Meine Lösung. Ich spezialisiere die Methode Set Value und prüfe ob die indizes gleich sind:

    template <>
    void SetValue(const myvariant value)
    {
            if (value.index() != Value.index())
            {
                throw(...);
            }
    
        Value = value;
    }
    

    @HarteWare sagte in std::variant an anderen std::variant zuweisen wenn unterliegender Typ gleich.:

    Dann nimm doch einfach std::any, wenn du dich nicht auf 4 Typen beschränken willst.

    Ah ok, any kannte ich noch nicht. Danke dafür. (Muss man sich die std als Abendlektüre reinziehen dass man hier alle Funktionen kennt 🙂 )

    Aber ob der any in meinem Fall so passend ist weiß ich nicht.
    Zum einen muss ich den "Value" in ein json File serialisieren und deserializieren. Und zum anderen an ein andere Software via API übertragen das als Schnittstelle einen _variant_t entgegen nimmt.


Anmelden zum Antworten