Boost logo

Boost :

Subject: [boost] [variant] Common base type of variant sub-types
From: Adam Badura (abadura_at_[hidden])
Date: 2010-01-08 11:24:57


    Unions of POD types have a special case of allowing to access union
value members through any union value which has those members. This is
exemplified by following code:
----------
struct base
{
  int shared;
};

struct derived_1 : base
{
  int shared_as_well;
  int not_shared_1;
};

struct derived_2 : base
{
  int shared_as_well;
  int not_shared_2;
};

union union_type
{
  derived_1 value_1;
  derived_2 value_2;
}

void f()
{
  union_type v;

  v.value_1 = derived_1();
  v.value_2.shared = 1; // This is OK.
  v.value_2.shared_as_well = 1; // This is OK as well.
  //v.value_2.not_shared_2 = 1; // This is not OK.
}
----------

    Such feature is quite useful. Sadly it is not supported by
boost::variant.

    However a similar feature might be supported if boost::get was changed a
bit. Lets consider another example:
----------
#include <boost/variant.hpp>

struct base
{
  int shared;
};

struct derived_1 : base
{
  int almost_shared; // If union was used this would be shared as well.
  int not_shared_1;
};

struct derived_2 : base
{
  int almost_shared; // If union was used this would be shared as well.
  int not_shared_2;
};

typedef boost::variant<derived_1, derived_2> variant_type;

void f()
{
  variant_type v;

  v = derived_1();
  assert(boost::get<base>(&v)); // This will fail.

  v = derived_2();
  assert(boost::get<base>(&v)); // This will fail.
}
----------

    As can be seen boost::get fails if we specify a base type of a type
which object is stored in variant. However if it would not fail but succeed
we would have a feature similar to that special case with unions.
    And I know this can be done with visitor (just like boost::get is
implemented) however I think it would be useful to wrap this functionality
in a function.

    I think it is unlikely that such feature would break existing code.
However it possibly might. To avoid breaking existing code a function
similar to get could be introduced.

    I think I might implement this but I would prefer someone else to do
this. :)

    Adam Badura


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk