Boost logo

Boost Users :

Subject: Re: [Boost-users] [any] Is it possible to support polymorphism in boost::any?
From: Tang Jiang Jun (tangjiangjun_at_[hidden])
Date: 2010-09-06 14:54:03


After thinking deeper, I figure out a rough implementation for this idea,
and prove it can work with polymorphism. (It is just rough concept
verification, and need a lot of work to polish it and make it usable).

1. Add a build method that accept base class info,
        template<typename ValueType, typename BaseType1, typename BaseType2>
        static any create( ValueType* value)
        {
            any a;
            a.content = new holder<ValueType, BaseType1, BaseType2>(value);
            return a;
        }

2. Add a interface to placeholder to convert held to base class pointer,
        virtual void* get_converted_pointer( const std::type_info&
_typeinfo ) const = 0;

3. Pass base class info to concrete holder and implement previous interface,
        template<typename ValueType, typename BaseType1, typename BaseType2>
        class holder : public placeholder

            virtual void* get_converted_pointer( const std::type_info&
_typeinfo ) const
            {
                if( _typeinfo == typeid( ValueType ) || _typeinfo == typeid(
BaseType1 ) )
                {
                    return held;
                }
                else if( _typeinfo == typeid( BaseType2 ) )
                {
                    return static_cast< BaseType2* >( held );
                }
                else
                {
                    return 0;
                }
            }

4. Modify any_cast to use this interface,
    template<typename ValueType>
    ValueType * any_cast(any * operand)
    {
        if( !operand ) return 0;

        return (ValueType*)operand->content->get_converted_pointer(
typeid(ValueType) );
    }

5. After that we can use boost:any as a type-safe and polymorphic variant
pointer. Here is the sample.
struct A
{
    A( int _a = 0 ) : a( _a ) {}
    int a;
};

struct B
{
    B( int _b = 0 ) : b( _b ) {}
    int b;
};

struct C : public A, public B
{
    C( int _a = 0, int _b = 0, int _c = 0 ) : A( _a ), B( _b ), c( _c ) {}
    int c;
};

void afoo( any& _any )
{
    A* pa = any_cast< A >( &_any );
    if( pa )
    {
        cout << "A - " << pa->a << endl;
    }
}

void bfoo( any& _any )
{
    B* pb = any_cast< B >( &_any );
    if( pb )
    {
        cout << "B - " << pb->b << endl;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{

    any a = any::create< C, A, B>( new C( 1, 2, 3 ) );

    afoo( a );
    bfoo( a );

    return 0;
}

On Tue, Sep 7, 2010 at 12:31 AM, Germán Diago <germandiago_at_[hidden]> wrote:

> I had exactly the same problem with some code of mine.
>
> The code was a factory like this
>
> typedef Factory<std::function<boost::any ()> > Factory_t;
>
> I wanted to store objects derived from a class (in this case, but I also
> wanted
> to support types not rooted in the same object hierarchy) and I was
> surprised that
> it failed. I think the right thing would do to work under these
> assumptions as well.
>
> 2010/9/6 Tang Jiang Jun <tangjiangjun_at_[hidden]>:
> > Hello,
> > It seems that boost::any does not support polymorphism in the following
> > sample.
> > class A {};
> > class B : public A {};
> > void foo( boost::any& _any )
> > {
> > try
> > {
> > A* p = any_cast< A* >( _any ); <-- Only succeed when _any contain a
> pointer
> > to a object that is exactly class A, but not any object that
> > is descendant of class A, like B.
> > do_some_thing( p );
> > }
> > catch( const bad_any_cast& )
> > {
> > }
> > }
> > void goo()
> > {
> > A* pa = new B;
> > boost::any a = pa;
> > foo( a );
> > }
> > Is it possible to make it support this polymorphism usage? Because
> > boost::any is a type-safe replacement of void*, I hope that boost::any
> has
> > the same polymorphic behavior as void*.
> > Regards,
> > Tang Jiang Jun
> >
> > _______________________________________________
> > Boost-users mailing list
> > Boost-users_at_[hidden]
> > http://lists.boost.org/mailman/listinfo.cgi/boost-users
> >
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net