
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