0

Thank you very much for your time I really appreciate it

There is a templatized subclass that needs to be serialized with the Cereal Serialization Library, the baseclass is empty, it only exists so we can have a vector of shared_ptr to the base class allowing it to hold multiple types of the templatized subclass, effectively allowing vector storage of multiple variable types.

class NetVar_ {};
template <class VARTYPE> class NetVar : public NetVar_
{
public:
    NetVar(VARTYPE Value)
    {
        Var = Value;
    }

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

private:
    VARTYPE Var;
};

The following vector of the baseclass is pushed a few of the subclasses:

std::vector<std::shared_ptr<NetVar_>> PacketData;
PacketData.push_back(std::make_shared<NetVar<int>>(32));
PacketData.push_back(std::make_shared<NetVar<int>>(32));
PacketData.push_back(std::make_shared<NetVar<std::string>>('test'));

Finally, the vector is serialized and sent off to a remote machine for processing:

std::ostringstream SData;
{
    cereal::PortableBinaryOutputArchive Archive(SData);
    Archive(PacketData);
    //SData is sent to remote machine here through networking library.
}

I must be missing a key piece to the puzzle because when I deserialize the data the program throws an exception, if I debug the values of the output variables are either blank or large negative numbers which leads me to believe the baseclass and or subclass is not getting serialized properly.

The code has been simplified down to only expose the issue, for more information about the complete idea you can refer to this question here.

The following Cereal headers are being included:

#include <cereal\archives\portable_binary.hpp>
#include <cereal\types\vector.hpp>
#include <cereal\types\memory.hpp>
#include <cereal\types\string.hpp>

I'm sure I'll need more as I start to add more types of data into the baseclass.

If someone has any idea what's going on here I would greatly appreciate it.

Thank you again for your time.

Community
  • 1
  • 1
KKlouzal
  • 732
  • 9
  • 32
  • Where it says: `Finally, the vector is serialized and sent off to a remote machine for processing:` That code snippet, are you sure that is right? It doesn't look right. That archive is destroyed as soon as it leaves that local scope. Also, classes cannot/should not start with an underscore.. – Brandon Apr 12 '14 at 20:06
  • There is additional code taking the data from the std::stringstream and sending it through a network library to a remote machine where it is reconstructed. Why should it not start with an '_'? :) – KKlouzal Apr 12 '14 at 20:12
  • Names beginning with an underscore or a double underscore are reserved: http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier – Brandon Apr 12 '14 at 20:17
  • Okay thank you, that has been changed, however it did not effect the classes serialization at all. :/ – KKlouzal Apr 12 '14 at 20:19

1 Answers1

1

You do not have the choice here, polymorphism need virtuality when you have only access to a base class interface. it prevents also Archive to be a template type.

I imagine cereal is doing some SFINAE to test the existence of the serialize method and have a default behavior if not found. That would be the case here as you do not have compilation error.

galop1n
  • 8,573
  • 22
  • 36
  • The program knows on both ends which type of data is in the vector and in which order, in the example we add int, int, string. On the remote machine it reads it in the same order int, int, string. Is there absolutely no way to get my class serialized? I am already able to add/get data just fine, it's just not serializing correctly. – KKlouzal Apr 12 '14 at 20:14
  • The user code may, but the generic call to `PortableBinaryOutputArchive::operator( aStdVectorOfT ) ` do not rely on user code. If you know the order, you are able to archive element one by one instead with the appropriate type cast, but type casting like that are signs of bad design most of the time. – galop1n Apr 12 '14 at 20:19
  • Bad designs aside it must be done this way. The amount and types of variables added into the vector is known to the programmer but unknown to the function. This allows the programmer to add multiple types of multiple variables into the vector and send it off to a remote machine for processing. The programmer is required to read the variable types in the same order they write them and in no circumstances should they attempt to read more variables than were written. – KKlouzal Apr 12 '14 at 20:23