Boost logo

Boost :

Subject: Re: [boost] [DynamicAny] Feedback
From: Daniel Larimer (dlarimer_at_[hidden])
Date: 2011-03-04 10:34:37


On 3/4/11 6:46 AM, "joaquin_at_[hidden]" <joaquin_at_[hidden]> wrote:

> Stewart, Robert escribió:
>> joaquin_at_[hidden] wrote:
>>
>>> Daniel Larimer escribió:
>>>
>>>
>>>> I recently ran into a problem where I wanted to retrieve
>>>> the value stored in a boost::any by casting to a base class.
>>>> Unfortunately, boost::any requires you cast out the exact
>>>> type as that held.
>>>>
>>>> Boost.DynamicAny is a vairant on Boost.Any which provides
>>>> more flexible dynamic casting of the underlying type. Whereas
>>>> retreiving a value from Boost.Any requires that you know the
>>>> exact type stored within the Any, Boost.DynamicAny allows you
>>>> to dynamically cast to either a base or derived class of the
>>>> held type.
I misspoke, you cannot cast to a more-derived type than that held..

>>>>
>>> What's the trade-off? I mean, does Boost.DynamicAny use more
>>> memory than Boost.Any, is it slower?

Memory usage should be the same, compile times may increase slightly as a
helper template was needed to separate the scalar vs non-scalar
implementation. Runtime dynamic cast performance will be slower than the
compile time static cast in boost::any. Static cast is still used for
scalar types.

>>>
>>
>> I presume you mean other than the difference between static_cast
>> and dynamic_cast?
>>
>> Couldn't this functionality be added to Boost.Any itself? That is,
>> add another cast that does dynamic_cast so there's only one
>> library but clients get a choice about how to extract values.

The change is perhaps a bit to fundamental. Here is the "effective
difference".

struct any
{
    struct holder_base{};
    template<typename T>
    struct holder_impl<T> : holder_base
    {
        T held;
    };
    holder_base* data;
}

struct dynamic_any
{
    struct holder_base{};
    template<typename T>
    struct holder_impl<T> : T, virtual holder_base {};
    holder_base* data;
};

With the extra layer of inheritance, there is some potential for conflicts
with the clone() and type() virtual methods provided by holder_impl<> and
any method of the same name provided by T. These conflicts could be
mitigated by changing the name to __dynamic_any__clone() /type().

I had assumed there was a solid design rational for using aggregation vs
inheritance in boost::any and it is probably related to it having less
restrictions on the type that can be held.

In my original email I thought it would be easy to add support for casting
dynamic_any(derived*) to dynamic_any(base*), but because I cannot inherit
from a pointer, I have no way to get the RTTI info required to know that
derived inherits base or what the offset is. If anyone has a way to
polymorphically determine whether base* is inherited by derived* and if so
perform the proper pointer offsets to do a cast let me know.

>>
>
> That is exactly my point.
>
> Joaquín M López Muñoz
> Telefóinca, Investigación y Desarrollo
>
> Este mensaje se dirige exclusivamente a su destinatario. Puede consultar
> nuestra política de envío y recepción de correo electrónico en el enlace
> situado más abajo.
> This message is intended exclusively for its addressee. We only send and
> receive email on the basis of the terms set out at.
> http://www.tid.es/ES/PAGINAS/disclaimer.aspx
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


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