Boost logo

Boost Users :

Subject: Re: [Boost-users] serilalization of union
From: Andrew Holden (aholden_at_[hidden])
Date: 2009-01-07 13:42:31


Robert Ramey wrote:
> Steven Watanabe wrote:
>> AMDG
>>
>> niranjan bangera wrote:
>>> union myunion
>>> {
>>>
>>> uint32_t a;
>>> float t;
>>>
>>> template <class Archive>
>>> void serialize(Archive & ar, const unsigned int file_version)
>>> {
>>>
>>> ar & a;
>>> ar & t;
>>>
>>> }
>>
>> This is undefined behavior. a and t cannot both be valid at the same
>> time.
>
> LOL - makes me wonder if I'm even reading these emails.
>
> One could do try:
>
> struct myunion {
> union {
> uint32_t a;
> float t;
> } x;
> operator (uint32_t &)(){ // i forget the exact casting operator syntax
> return a;
> }
> operator(float &t)(){
> return t;
> }
> template<class Archive>
> void serialize(Archive & ar, const unsigned int file_version){
> ar & binary_object(sizeof(x), &x);
> }
> };
>
> crude - but effective.
>
> Robert Ramey

The best solutions would become more obvious if you know which type is valid at a higher level. For example, if you have a structure like this:

struct UnionWrapper
{
  myunion the_union;
  bool is_float; /* Set to true if and only if the float member is used */

  template <class Archive>
  void serialize (Archive &ar, unsigned int const version)
  {
    ar & is_float; /*Do this first so deserialization knows which union member to get. */

    if (is_float)
    {
      ar & the_union.t;
    }
    else
    {
      ar & the_union.a;
    }
  }
};


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net