How to serialize a variable of type std::variant, and then a vector of std::variants of structs?

771 views
Skip to first unread message

Grant Rostig

unread,
Jan 13, 2020, 4:29:55 PM1/13/20
to cereal serialization library
Hi, I'm new and spent several hours trying to serialize a variant with no success.  I have included my various attempts in the code below, file is also attached.
Essentially while I did get structs and vectors to work, any use of std::variant has eluded me.  Can someone point me to an example, the documentation, or fix the compile errors in the below code for "vec", "vec4" and "variant1".  Any assistance is appreciated.

#include <iostream>
#include <variant>
#include <string>
#include <vector>
#include <sstream>
#include <cereal/archives/binary.hpp>
#include <cereal/types/vector.hpp>
#include <cereal/types/variant.hpp>

struct S1 {
    int a {};
    template< class Archive >
    void serialize( Archive & archive ) {
        archive( a );
    }
};
struct S2 {
    std::string b {};
    template< class Archive >
    void serialize( Archive & archive ) {
        archive( b );
    }
};
using Svariant = std::variant<S1,S2>;
struct Data {
    int my_int {5};
    template< class Archive>
    void serialize( Archive & archive ) {
        archive( my_int );
    }
};
struct Datas1 {
    S1 my_s1 {5};
    template< class Archive>
    void serialize( Archive & archive ) {
        archive( my_s1 );
    }
};
struct Vec {
    int my_int {5};
    std::vector<Svariant> vec { S1 {3}, S2 {"hello"}, S1 {4} };
    template< class Archive>
    void serialize( Archive & archive ) {
        archive( vec, my_int );
    }
};
struct Vec2 {
    int my_int {5};
    std::vector<S1> vec { S1 {3}, S1 {4} };
    template< class Archive>
    void serialize( Archive & archive ) {
        archive( vec, my_int );
    }
};
struct Vec3 {
    int my_int {5};
    std::vector<int> vec { 3, 4 };
    template< class Archive>
    void serialize( Archive & archive ) {
        archive( vec, my_int );
    }
};
struct Variant1 {
    //Variant1() = default;  // does this add anything?
    std::variant<int,std::string> data {"hello"};
    template< class Archive>
    void serialize( Archive & archive ) {
        archive( data );
    }
};
struct Vec4 {
    int my_int {5};
    std::vector<Variant1> vec { Variant1 {3}, Variant1 {"hello"}, Variant1 {4} };
    template< class Archive>
    void serialize( Archive & archive ) {
        archive( vec, my_int );
    }
};
int main() {
    std::stringstream ss; // any stream can be used
    {
        cereal::BinaryOutputArchive oarchive(ss);
        Data data {42};
        Datas1 datas1 {42};
        Vec vec {};
        Vec2 vec2 {};
        Vec3 vec3 {42, {43,44}};
        Vec4 vec4 {42, std::vector {Variant1 {43} , Variant1 {"bye"}, Variant1 {44}}};
        Variant1 variant1 {"bye"};
        //oarchive( data ); // works
        //oarchive( datas1 ); // works
        //oarchive( vec );  // compile error
        //oarchive( vec2 ); // works
        //oarchive( vec3 ); // works
        //oarchive( vec4 ); // compile error
        oarchive( variant1 );   // compile error
    }     // archive goes out of scope, ensuring all contents are flushed
    {
        cereal::BinaryInputArchive iarchive(ss);
        Data data {};
        Datas1 datas1 {};
        Vec vec {};
        Vec2 vec2 {};
        Vec3 vec3 {};
        Vec4 vec4 {};
        Variant1 variant1 {};
        //iarchive(data); // works
        //iarchive( datas1 ); // works
        //iarchive( vec );  // compile error
        //iarchive( vec2 ); // works
        //iarchive( vec3 ); // works
        //iarchive( vec4 );   // compile error
        iarchive( variant1 );   // compile error
    }
}



main.cpp

Julius Rapp

unread,
Jan 13, 2020, 5:12:09 PM1/13/20
to cereal serialization library
Hey Grant,

if I add the include

#include <cereal/types/string.hpp>

then your code seems to work.

For compilation, I am using GCC 9.2.0 with the following command:

g++ main.cpp -std=c++17 -isystem /full/path/to/cereal/include

Does that help?

Best,
Julius

Grant Rostig

unread,
Jan 13, 2020, 11:02:24 PM1/13/20
to cereal serialization library
Thanks to Julius, yes adding the missing line fixed it.  Thank you.
#include <cereal/types/string.hpp>
Reply all
Reply to author
Forward
0 new messages