Boost logo

Boost Users :

From: Björn Karlsson (bjorn.karlsson_at_[hidden])
Date: 2001-12-11 04:20:42


> From: rz0 [mailto:rz0_at_[hidden]]
> Hi Bjorn
>
> Thank you very much for the reply.
>
> Unfortunately these classes are provided to me and as part of the
> requirements, I must be able to work with them. In re-thinking the
> problem, it seems that I'm in desperate need of a polymorphic
> container - i.e.:
>
>
> Does boost have any polymorphic containers?
>
> Thanks very much in advance.
>
>

I don't think that polymorphism is the cure - you'll always need to downcast
the pointer as the signatures differ. However, there is support in Boost for
what you're trying to do - through boost::any. Like I said before, the
solution will not be very clean, but it will work.
The code snippet below seems to do what you're asking for:

#include <iostream>
#include <algorithm>
#include <vector>
#include <Boost\Any.hpp>

class A
{
public:
        virtual void func1() { std::cout << "A::func1()\n"; };
};

class B : public A
{
public:
        void func1() { std::cout << "B::func1()\n"; };
        void funcB() { std::cout << "B::funcB()\n"; };
};

class C : public A
{
public:
        void func1() { std::cout << "C::func1()\n"; };
        void funcC() { std::cout << "C::funcC()\n"; };
};

typedef std::vector<boost::any> AnyVector;

void DoStuffWithAny(boost::any& a)
{
        // Try with a B
        if ( B* pB = boost::any_cast<B>(&a) )
        {
                pB->func1();
                pB->funcB();
        }
        // Try with a C
        else if ( C* pC = boost::any_cast<C>(&a) )
        {
                pC->func1();
                pC->funcC();
        }
        // Try with an A
        else if ( A* pA = boost::any_cast<A>(&a) )
        {
                pA->func1();
        }
}

void DoStuffWithAnyPointer(boost::any& a)
{
        // Try with a B
        if ( B** ppB = boost::any_cast<B*>(&a) )
        {
                (*ppB)->func1();
                (*ppB)->funcB();
        }
        // Try with a C
        else if ( C** ppC = boost::any_cast<C*>(&a) )
        {
                (*ppC)->func1();
                (*ppC)->funcC();
        }
        // Try with an A
        else if ( A** ppA = boost::any_cast<A*>(&a) )
        {
                (*ppA)->func1();
        }
}

int main(int argc, char* argv[])
{
        AnyVector aVector;

        A a;
        B b;
        C c;

        aVector.push_back(a);
        aVector.push_back(b);
        aVector.push_back(c);

        // Do interesting things
        std::for_each(aVector.begin(), aVector.end(), DoStuffWithAny);

        AnyVector anotherVector;

        anotherVector.push_back(new A);
        anotherVector.push_back(new B);
        anotherVector.push_back(new C);

        // Do interesting things
        std::for_each(anotherVector.begin(), anotherVector.end(),
DoStuffWithAnyPointer);

        return 0;
}

Another approach would be to provide adapters, but I'm guessing that
wouldn't be worth the trouble.
HTH,

Bjorn Karlsson

[Non-text portions of this message have been removed]


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