2016-01-20 5 views
5

Ist es möglich, eine boost::ptr_vector Instanz mit Müsli zu serialisieren? Wenn das so ist, wie?Wie boost :: ptr_vector mit Getreide zu serialisieren?

+2

Ich bin nicht vertraut mit 'ptr_vector', aber es sieht aus wie es ist im Wesentlichen ein Wrapper um' std :: vector '. Cereal unterstützt keine rohen Pointer, daher halte ich es für unwahrscheinlich, dass Sie einen 'ptr_vector' serialisieren können, ohne wesentliche Änderungen an Cereal oder eine komplizierte Umgehungslösung. – Azoth

Antwort

3

Es ist definitiv möglich. Sie können auf dem Archiv und Zeigertyp wie diese externen save() und load() Template-Funktionen erstellen:

#include <iostream> 
#include <sstream> 
#include <boost/ptr_container/ptr_vector.hpp> 
#include <cereal/archives/binary.hpp> 
#include <cereal/types/string.hpp> 

// Sample serializable object. 
struct MyRecord { 
    std::string s_; 

    MyRecord(const std::string s = std::string()) 
     : s_(s) { 
    } 

    template <class Archive> 
    void serialize(Archive& ar) { 
     ar(s_); 
    } 
}; 

// External save function for boost::ptr_vector<T>. 
template<class Archive, class T> 
void save(Archive& ar, const boost::ptr_vector<T>& pv) { 
    ar(pv.size()); 
    for (const auto& element : pv) 
     ar(element); 
} 

// External load function for boost::ptr_vector<T>. 
template<class Archive, class T> 
void load(Archive& ar, boost::ptr_vector<T>& pv) { 
    size_t n; 
    ar(n); 

    pv.reserve(n); 
    for (size_t i = 0; i < n; ++i) { 
     pv.push_back(new T); 
     ar(pv.back()); 
    } 
} 

int main() { 
    // Serialize a boost::ptr_vector to a buffer. 
    std::ostringstream os; 
    { 
     boost::ptr_vector<MyRecord> saved; 
     saved.push_back(new MyRecord("how")); 
     saved.push_back(new MyRecord("now")); 
     saved.push_back(new MyRecord("brown")); 
     saved.push_back(new MyRecord("cow")); 

     cereal::BinaryOutputArchive oa(os); 
     oa(saved); 
    } 

    // Serialize from the buffer. 
    boost::ptr_vector<MyRecord> loaded; 
    { 
     std::istringstream is(os.str()); 
     cereal::BinaryInputArchive ia(is); 
     ia(loaded); 
    } 

    for (const auto& element : loaded) 
     std::cout << element.s_ << '\n'; 

    return 0; 
} 

Dies sollte mit jeder enthaltenen Art arbeiten, die Standard-konstruierbar ist und bereits einzeln serializable.

+0

.... und für die die Überladungen für 'save' und' load' in einem _associated namespace_ (vgl. ADL) gefunden werden. Ich könnte hinzufügen, dass diese Version eine ziemlich witzige Konstruktionssemantik beim Laden hat. Es ist "ok", weil ptr_vectors sowieso keine Aliasing-Elemente haben können – sehe

+0

@sehe, mit der witzigen Ladesemantik meinen Sie, dass dies effizienter gemacht werden kann? –

+0

Eigentlich, nein, es sieht gut aus. – sehe

Verwandte Themen