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@gmail.com> 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@gmail.com>:
> 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@lists.boost.org
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>
_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users