Boost logo

Boost :

From: Persson Jonas (jonas.persson_at_[hidden])
Date: 2003-11-04 09:52:01

> -----Original Message-----
> From: Eric Friedman [mailto:ebf_at_[hidden]]
> Sent: den 4 november 2003 00:46
> To: Persson Jonas
> Subject: Re: Variant size bug?
> > Well, I would argue that it is a (design) bug. It breaks the
> > typelist <-> variant symmetry, and causes some of the mpl stuff to
> > give the wrong result.
> Before I comment on this, do you mean the (implementation) bug you
> identified elsewhere in this thread?
No, I had not figured that one out yet when I wrote this.

> If so, as I replied to your message, that bug has been fixed.
Yes, thanks. It did solve some other issues too where mpl did not
work on variant::types.

> Well, yes: variant<> *is* variant<boost::empty>.
> As it stands currently,
> there is no such thing as a variant with no content; the closest
> approximation is a variant with boost::empty content.
Yes I understand that, but *why*? What are the conceptual reasons
for not allowing truly empty variants?

Consider for example a metaprogram that takes two variant types and
forms a new type that is the union of these two.
With the current design we will get:

variant<int,float> + variant<std::string> -> variant<int,float,std::string>

This works as I would expect, but:

variant<int,float> + variant<> -> variant<int,float,boost::empty>

does not. I expected a variant identical to the one on the left hand side, but I got one that differs in behaviour. Compare this to a mpl sequence:

vector<int,float> + vector<std::string> -> vector<int,float,std::string>
vector<int,float> + vector<> -> vector<int,float>

I could add code that filters out boost:empty types, but that feels more like a hack. And there is the risk that it get lost in places where it is not supposed to.
The problem here is that boost::empty sometimes means that the variant is allowed to be unassigned and sometimes means that the variant contains no types.

> > I use mpl to unroll the types in the variant, so I must have a
> > termination condition. As it stands now I cannot use mpl::size or
> > mpl::empty for that. How do I check at compile time if the variant
> > contains any types or not?
> Again, you'll have to be clearer.

For example the following simple function that recurses over
the types in the variant. If an empty variant hold an boost::empty
type I cannot detect the end condition. I could try to detect if the
last type is boost:empty, but then I get into difficulties differing
between variant<int,boost::empty> and variant<int>.

template<class V>
fun(V const& v) {
  // ...

template<class V>
fun(V const& v) {
  typedef typename mpl::pop_front<V::types>::type TailTypes;
  variant<TailTypes> v2;
  // ...

        / Jonas

Boost list run by bdawes at, gregod at, cpdaniel at, john at