|
Boost : |
Subject: Re: [boost] [variant] Why boost::get<Base>(derived) not supported?
From: Larry Evans (cppljevans_at_[hidden])
Date: 2013-12-07 12:29:59
On 12/07/13 10:37, Larry Evans wrote:
> On 12/07/13 10:21, TONGARI J wrote:
>> 2013/12/7 TONGARI J <tongari95_at_[hidden]>
>>
>>> 2013/12/7 Antony Polukhin <antoshkka_at_[hidden]>
>>>
>>>> 2013/12/7 TONGARI J <tongari95_at_[hidden]>
>>>> <...>
>>>>
>>>>> Maybe we can promote this idea to something more general, like
>>>>> 'variant_cast', not necessary have to be in base-derived relationship
>>>> but
>>>>> just something convertible.
>>>>>
>>>>> Does that make sense?
>>>>>
>>>>
>>>> I'd prefer not mixing functionalities. We can make polymorphic_get<>
>>>> work
>>>> only for polymorphic casts (Base and Derived can be checked using type
>>>> trait).
>>>>
>>>
>>> I just looked into the code of get, and it also uses visitor, a bit
>>> disappointed.
>>> Since the current boost::get requires exact type match (except const),
>>> there's only one viable way from the types, I thought it might do better
>>> under the hood (i.e. single if-check instead of switch), but it didn't,
>>> it's just a more restrictive visitor than what I shown in my sample
>>> code.
>>>
>>> And for type-checking, I think the user should use .which(), but I don't
>>> know how many ones already did that with get, so it's a valid concern
>>> not
>>> to break others' code...otherwise I'm inclined to make it the default
>>> behavior of boost::get.
>>>
>>> I'm OK with polymorphic_get (except the long name, though), since that's
>>> my use-case.
>>> But variant_cast seems more attractive.
>>> You can do variant_cast<Base&>(derived) or variant_cast<Base*>(&derived)
>>> in that case, and variant_cast<Compatible>(v) for other conversion.
>>> If you want to go further, you can ensure that at least one viable
>>> conversion exists at compile time by some metaprogramming tricks.
>>>
>>
>> Aside: Do we have something like unconditional_get that doesn't
>> perform the
>> runtime check?
>
> Wouldn't reinterpret_cast do?
>
OOPS. The storage_ member variable is stored after the which_ tag
as shown on lines 1237 and 1275 of here:
https://github.com/boostorg/variant/blob/master/include/boost/variant/variant.hpp
Also, the storage_ member variable maybe does not start with
the actual storage. Instead, looking at some of the code
shows it's reached by:
storage_.address()
So, I was wrong about using reinterpret_cast, and I've no idea
how to do it without modifying the variant code, maybe by providing
acciess to storage_.address().
-regards,
Larry
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk