2017-05-07 4 views
2

Ich versuche Cereal zu verwenden, um ein Objekt ohne Standardkonstruktor zu serialisieren. Das Speichern solcher Objekte direkt oder über Smartpointer funktioniert. Allerdings wenn ich das Objekt in einen Behälter gegeben, es kompiliert nicht mehr:Cereal: Deserialize einen Vektor von Objekten ohne Standardkonstruktor

error: no matching function for call to ‘Node::Node()’

Gibt es eine Möglichkeit Getreide zu bekommen zu speichern/wiederherstellen Vektoren von Objekten ohne Standardkonstruktors?

Mein Testcode:

#include <fstream> 
#include <cereal/archives/json.hpp> 
#include <cereal/types/memory.hpp> 
#include <cereal/types/vector.hpp> 


class Node { 
public: 
    Node(int* parent) {}; 

    int value_1; 

    template<class Archive> 
    void serialize(Archive& archive) { 
     archive(
       CEREAL_NVP(value_1) 
     ); 
    } 

    template<class Archive> 
    static void load_and_construct(Archive& archive, cereal::construct<Node>& construct) { 
     construct(nullptr); 
     construct->serialize(archive); 
    } 
}; 

int main() { 
    std::string file_path = "../data/nodes.json"; 
    Node node_1{nullptr}; // this would serialize 

    std::vector<Node> nodes; // this does not 
    nodes.push_back(Node{nullptr}); 
    nodes.push_back(Node{nullptr}); 

    std::vector<std::unique_ptr<Node>> node_ptrs; // this would serialize 
    node_ptrs.push_back(std::make_unique<Node>(nullptr)); 
    node_ptrs.push_back(std::make_unique<Node>(nullptr)); 

    { //store vector 
     std::ofstream out_file(file_path); 
     cereal::JSONOutputArchive out_archive(out_file); 
     out_archive(CEREAL_NVP(nodes)); 
    } 

    { // load vector 
     std::ifstream in_file(file_path); 
     cereal::JSONInputArchive in_archive(in_file); 
     in_archive(nodes); 
    } 

    return 0; 
} 

Antwort

0

Soweit ich die Art und Weise dieser Bibliothek Werke verstehen, gibt es keine Möglichkeit, etwas deserialisieren, die nicht über einen Standardkonstruktor zumindest hat für dynamisch zugewiesenen Objekte.

Die Logik unter das ist die folgende:

  1. Sie benötigen vector<Node>
  2. Um deserialisieren zu tun, dass Sie eine angemessene Menge an Speicher
  3. Getreide nicht weiß, über die zuweisen müssen Konstruktor und kann Objektspeicher nicht ordnungsgemäß selbst zuweisen
  4. Um ein ordnungsgemäßes Objekt erstellen bereitzustellen, erfordert es den Standardkonstruktor
+1

Stellen Sie sich vor, Sie würden einen Typ laden, der keinen Standardkonstruktor hat. Die Schnittstelle zu der Serialisierung von Cerealien erfordert, dass Sie eine Referenz an das Objekt übergeben, das mit serialisierten Daten instanziiert werden soll. Wenn kein Standardkonstruktor vorhanden ist, müssen Sie (der Benutzer) ein solches Objekt bereits initialisiert haben, bevor Cereal es überhaupt sieht. Die Alternative ist, dass Cereal die eigentliche Konstruktion des Objekts durchführt, was nur mit dynamisch erzeugten (d. H. Zeigern) Objekten geschehen kann, so dass Cereal die Argumente vorladen kann, die an den Konstruktor übergeben werden, wie in "load_and_construct". – Azoth

Verwandte Themen