6

boost::variant claims that it is a value type. Does this mean that it's safe to simply write out the raw representation of a boost::variant and load it back later, as long as it only contains POD types? Assume that it will be reloaded by code compiled by the same compiler, and same version of boost, on the same architecture.

Also, (probably) equivalently, can boost::variant be used in shared memory?

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • 1
    Spitting out the raw memory representation, even if it's just a structure of PODs, is a poor idea, and subjects you to the mercy of your compiler's padding layout, architecture details, and endianness. – Thanatos Aug 06 '10 at 02:23
  • At the time I was more interested in shared memory usage, in which differences in layout weren't going to be a problem at all. – bdonlan Aug 06 '10 at 04:16

3 Answers3

15

Try just including boost/serialization/variant.hpp; it does the work for you.

spiderlama
  • 1,539
  • 15
  • 10
  • seeings as boost::variant was made for non POD types (otherwise you could use a tagged union), I would assume yes, but a quick test would confirm. – spiderlama Sep 08 '16 at 15:57
7

Regarding serialisation: It should work, yes. But why don't you use boost::variant's visitation mechanism to write out the actual type contained in the variant?

struct variant_serializer : boost::static_visitor<void> {
    template <typename T>
    typename boost::enable_if< boost::is_pod<T>, void>::type
    operator()( const T & t ) const {
        // ... serialize here, e.g.
        std::cout << t;
    }
};

int main() {

    const boost::variant<int,char,float,double> v( '1' );

    variant_serializer s;
    boost::apply_visitor( s, v );

    return 0;
}

Regarding shared memory: boost::variant does not perform heap allocations, so you can place it into shared memory just like an int, assuming proper synchronisation, of course.

Needless to say, as you said, the above is only valid if the variant can only contain POD types.

Marc Mutz - mmutz
  • 24,485
  • 12
  • 80
  • 90
0

The memory layout of boost::variant is as: { int which; storage_t storage;}. The storage_t is determined by the implementation to be the max size required by your usage. so if your storage_t turns out to be 8-byte or more (OR requiring an 8-byte alignment), there might be a 4-byte padding involved between 'which' and 'storage', depending upon the compiler or compiler options. So as the accepted answer says, it is safer to serialize using visitation.

sanjivgupta
  • 396
  • 3
  • 12