Boost logo

Boost :

From: Jaap Suter (j.suter_at_[hidden])
Date: 2003-10-29 04:27:08

> > So can I assume Boost.Variant can detect non-throwability and act
> > accordingly (not do an allocation if not necessary)?
> Yes, via the type_traits library. Without compiler support, however, you
> likely will need to specialize the appropriate type_traits templates for
> your user-defined types.

Is it possible to document which type_traits specifically I need to
specialize. No hurries, and I haven't actually put in any effort to find out
which ones myself, but it might be nice.

> > Brian does bring up another point, which is the order of destruction and
> > construction. Is this garantueed, or merely a consequence of the current
> > implementation scheme? Is it possible to make the order of dtor and
> > (copy-)ctor an explicitly document feature that can be relied upon?
> It is not guaranteed. For example, since changing from double-storage to
> temporary heap backup, the order has reversed. I'm not sure what the
> value of a guaranteed order would be anyhow.

Well, it allows me to do exactly the thing posted in the original message;
implement a state machine where state entries and exits are implemented
through ctors and dtors. I can probably think of a few other cases where
such a defined order can be exploited too.

Personally, I think it makes sense conceptually too. If I use the assignment
operator on any other class, then in a sense the existing state is destroyed
first, and then the new state is copied in. I'm not saying that it's
implemented like that (as no sane person would do), but the similarities are
there. I think it makes sense to let variant behave the same.

On the other hand, I can also do what I am doing as a hack now, and use
boost::empty as follows:

variant<boost::empty, foo, bar> v;
v = foo();
v = boost::empty(); // make sure that foo is destroyed first;
v = bar(); // and then construct bar.

With an in_place construct, this wouldn't even be any slower than allowing
the actual implementation to define the order.

Thoughts, anyone?

> I think this would be better handled with code such as the following:
> int p = mpl::index_of< my_variant::types, float >::value;
> Unfortunately, mpl::index_of does not yet exist. Perhaps this is enough
> motivation for me to finally create it.

That makes sense, and I wrote exactly that today actually :). It was
something like:

template<class Sequence, class Element>
struct index_of : mpl::distance<
        typename mpl::begin<Sequence>::type,
        typename mpl::find<Sequence, Element>::type

Probably the coding style isn't mpl compatible, but it's just to prove that
it's an easy enough addition.

Anyway, my work lead to the following questions:

1. I'm using MSVC 7.0, which means I can't use the variant<list<types> >
method. Is this really not implementable on 7.0, or is it simply too much
work. I thought of a few ways myself to do it without PTS, but I'm probably
overlooking something.
2. Is the 'variant::types' typedef a type that models the mpl::sequence
concept? I tried running a few algorithms over it, but not everything
compiled. Therefore, as an temporary solution, I'm now simply defining both
a vector of types, and a variant of the same types (not using the vector
because I'm on MSVC). When I need to get the index, I just apply index_of to
the vector, instead of using variant::types.


Jaap Suter

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