Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2001-07-15 15:01:06


From: "Corwin Joy" <cjoy_at_[hidden]>
> --- In boost_at_y..., "Peter Dimov" <pdimov_at_m...> wrote:
> > Could you please provide an example of such a design? This is quite
> > interesting.
>
> Sure. We have a variant class in the Database Template Library that I
> co-authored (http://www.geocities.com/corwinjoy/dtl/index.htm). What
> happens is that at construction time, the program analyzes the table being
> bound to and determines the types of the columns such as date, string,
> integer, wide-string etc. Once these types have been determined a variant
> is constructed to hold each database column. After initial construction,
> any writes into this variant class are not allowed to change the variant's
> type (otherwise the database binding would become invalid). So, writes
into
> the variant are cast into whatever type is currently held by the object.
If
> the cast cannot be performed, a runtime exception is thrown.

Aha, I see. This, too, can be done without touching the 'any' class, if you
register the inserters beforehand.

> This sounds interesting - I'm not quite sure how the register methodology
> works with the held value type. I'd be interested to see how you
integrate
> the register templates shown above with the virtual mechanism required by
> the holder class for any.

It probably can be done if one insists, but a std::map of typeid's will work
just fine. Operations on 'any' aren't supposed to be time critical. :-)

> Also, one other minor point, I think your
> extractors above would need some kind of notion of a terminating token(s)
so
> that string does not always win.

The string is terminated by whitespace. The infrastructure should support
multiple extractors for a given type, so it should be possible to register
another std::string extractor that responds to \"[^\"]*\" that can read
strings containing whitespace.

> > convert_to<int>(a); // returns 1, type int
> > convert_to<std::string>(a); // fails (std::bad_cast)
>
> This kind of thing would be really cool. Here I *really* can't see how
this
> would work with the virtual function mechanism required by any. How
exactly
> would you modify the placeholder class to do this. (Or were you planning
on
> a massive switch...case base on the type_info (shudder...) :-O ).

Yep, this is double dispatch... std::map keyed on a pair of typeid's is the
usual solution for the dynamic case.

> This would be awesome if it were possible. In practice I fear that the
> language constraints might make it hard to get here.

It's possible. It will not be as efficient as a hand-crafted 'variant' with
switch-on-type, but it will work, which is the important thing. :-)

Unfortunately you can't make a hash table keyed on std::type_info's. In
C++0x, maybe.

--
Peter Dimov
Multi Media Ltd.

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