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>
enable_if<mpl::empty<V::types>::value,void>
fun(V const& v) {
  // ...
}

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

        / Jonas


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