boost::any serialisieren



  • ich würde gerne meine boost::any-Variable serialisieren. Das soll mit allen Typen, die in any drin sind und für die es einen streaming-op gibt funzen und ansonsten nen Compiler-Fehler geben.

    d.h. ich will nicht sowas wie

    if(typeid(int) == anyVal.type())
    {
    strm << boost::any_cast<int>(anyVal);
    }

    schreiben müssen.

    Da gibst doch bestimmt was für.



  • Hm, die Ausgabe könntest du realisieren, indem du dein eigenes any schreibst, das sich die Adresse des zugehörigen operator<<s merkt. Aber da du vermutlich auch die Eingabe brauchst und das über die Gültigkeit von Speicheradressen hinaus, führt wohl nichts an einer manuellen Lösung vorbei 😞



  • hab jetzt irgendwie auf template-Zauberei gehofft.

    Andrerseits ist any natürlich ein Variant, und der Typ der drin ist, ist zur Compilezeit nicht bestimmbar ...



  • Das größte logische Problem daran ist, dass in der Datei am Ende nur noch Klartext steht, von dem man keinerlei Rückschlüsse mehr auf den ursprünglichen Typen ziehen kann. Da bräuchte man schon eine Gedanken lesende Sprache 🙂



  • @kartoffelsack
    Ich weiß nicht, ob es dir hilft, aber hast du dir schon mal dynamic-any angeschaut?

    http://www.cuj.com/documents/s=8837/cujweb0309nasonov/



  • Hm, wo ich nochmal drüber nachdenke, ginge das mit einer Implementierung, die ein aussagekräftiges type_info::name hat (also: MSVC, nicht GCC) immerhin noch relativ komfortabel, wenn es dich nicht stört, den Typen mitzuspeichern. So in etwa:

    // Ungetestet, aber ich habe gerade Lust auf Drauflostippen :)
    // Die Syntax könnte man auch etwas an boost::any angleichen...
    
    class string_any
    {
        std::string type, val;
    
    public:
        template<typename T>
        string_any& operator =(const T& rhs)
        {
            type = typeid(T).name();
            std::ostringstream stream;
            stream << rhs;
            val = stream.str();
        }
    
        template<typename T>
        T get() const
        {
            if (typeid(T).name() != type)
                throw std::logic_error("...");
            std::istringstream stream(val);
            T result;
            stream >> T;
            return result;
        }
    
        template<typename T>
        bool is_type() const
        {
            return typeid(T).name() == type;
        }
    };
    
    /* operator<< und >> für string_any speichern erst den Typen, dann den Wert */
    
    ...
    
    string_any sa;
    sa = 5;
    assert(sa.is_type<int>());
    int x = sa.get<int>();
    

    Keine Ahnung ob das hilft 😉


Anmelden zum Antworten