[variant] Why boost::get<Base>(derived) not supported?

Hi there, You can see the idea here: http://coliru.stacked-crooked.com/a/3e920faa604fa534 Is there any technical reason not having boost::get work like that? Thanks,

2013/12/7 TONGARI J
Hi there,
You can see the idea here: http://coliru.stacked-crooked.com/a/3e920faa604fa534
Is there any technical reason not having boost::get work like that?
I like the idea of polymorthic_get<>. Created a ticket https://svn.boost.org/trac/boost/ticket/9479 But I'm not sure that boost::get<> by default must work in that way. Won't there be ambiguity with `operator Base()`? And what if the user stores Base and Derived in boost::variant and want to chek that Base is stored in variant, not Derived? -- Best regards, Antony Polukhin

Hi Antony,
2013/12/7 Antony Polukhin
2013/12/7 TONGARI J
Hi there,
You can see the idea here: http://coliru.stacked-crooked.com/a/3e920faa604fa534
Is there any technical reason not having boost::get work like that?
I like the idea of polymorthic_get<>. Created a ticket https://svn.boost.org/trac/boost/ticket/9479
But I'm not sure that boost::get<> by default must work in that way.
Not a must, but intuitive to do so for me. Won't there be ambiguity with `operator Base()`? And what if the user
stores Base and Derived in boost::variant and want to chek that Base is stored in variant, not Derived?
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? Thanks,

2013/12/7 TONGARI J
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). -- Best regards, Antony Polukhin

2013/12/7 Antony Polukhin
2013/12/7 TONGARI J
<...> 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

2013/12/7 TONGARI J
2013/12/7 Antony Polukhin
2013/12/7 TONGARI J
<...> 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
(derived) or variant_cast (&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? Sometimes the type-safety can be ensured by my program logic. Thanks,

On 12/07/13 10:21, TONGARI J wrote:
2013/12/7 TONGARI J
2013/12/7 Antony Polukhin
2013/12/7 TONGARI J
<...> 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
(derived) or variant_cast (&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?
Sometimes the type-safety can be ensured by my program logic.
Thanks,
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 12/07/13 10:37, Larry Evans wrote:
On 12/07/13 10:21, TONGARI J wrote:
2013/12/7 TONGARI J
2013/12/7 Antony Polukhin
2013/12/7 TONGARI J
<...> 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
(derived) or variant_cast (&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/varian... 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

2013/12/7 TONGARI J
Aside: Do we have something like unconditional_get that doesn't perform the runtime check? Sometimes the type-safety can be ensured by my program logic.
There's nothing like that. But I really wish to believe that compilers are clever enough and will optimize away the `switch` in such cases. -- Best regards, Antony Polukhin
participants (3)
-
Antony Polukhin
-
Larry Evans
-
TONGARI J