|
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