Heterogeneous containers with CRTP

Discussion in 'C++' started by Arash Partow, May 15, 2007.

  1. Arash Partow

    Arash Partow Guest

    Hi all,

    I've got a question related to emulating aspects of polymorphism
    with CRTP. Below is a typical polymorphic class hierarchy with
    a definition of a "somewhat" heterogeneous container of objects.

    class poly_base
    {
    public: virtual int foo(int i, int j) = 0;
    };

    class poly_a : public poly_base
    {
    public: int foo(int i, int j) { return i + j; }
    };

    class poly_b : public poly_base
    {
    public: int foo(int i, int j) { return i * j; }
    };

    int boo(poly_base* p, int i, int j)
    {
    return p->foo(i,j);
    }

    int main()
    {
    poly_a a;
    poly_b b;
    poly_base* pa = &a;
    poly_base* pb = &b;

    std::vector<poly_base*> plist;
    plist.push_back(pa);
    plist.push_back(pb);

    int v = 0;
    for(std::vector<poly_base*>::iterator it = plist.begin();
    it != plist.end();
    ++it)
    {
    v += boo((*it),10,20);
    }
    return 0;
    }

    I was wondering how would one go about defining a container
    of crtp_base's similar to the definition of the vector above
    using the below structures.

    Is it even possible without using an interface that is abstract?

    template <typename T>
    class crtp_base
    {
    public: int foo(int i, int j) { return static_cast<T*>(this)-
    >foo(i,j); }

    };

    class crtp_a : public crtp_base<crtp_a>
    {
    public: int foo(int i, int j) { return i + j; }
    };

    class crtp_b : public crtp_base<crtp_b>
    {
    public: int foo(int i, int j) { return i * j; }
    };

    template<typename T>
    int boo(crtp_base<T>* p, int i, int j)
    {
    return p->foo(i,j);
    }

    int main()
    {
    crtp_a a;
    crtp_b b;
    crtp_base<crtp_a>* pa = &a;
    crtp_base<crtp_b>* pb = &b;
    boo(pa,10,20);
    boo(pb,10,20);
    return 0;
    }

    Any help would be much appreciated.


    Arash Partow
    __________________________________________________
    Be one who knows what they don't know,
    Instead of being one who knows not what they don't know,
    Thinking they know everything about all things.
    http://www.partow.net
     
    Arash Partow, May 15, 2007
    #1
    1. Advertising

  2. Arash Partow

    Salt_Peter Guest

    On May 14, 7:10 pm, Arash Partow <> wrote:
    > Hi all,
    >
    > I've got a question related to emulating aspects of polymorphism
    > with CRTP. Below is a typical polymorphic class hierarchy with
    > a definition of a "somewhat" heterogeneous container of objects.
    >
    > class poly_base
    > {
    > public: virtual int foo(int i, int j) = 0;
    >
    > };
    >
    > class poly_a : public poly_base
    > {
    > public: int foo(int i, int j) { return i + j; }
    >
    > };
    >
    > class poly_b : public poly_base
    > {
    > public: int foo(int i, int j) { return i * j; }
    >
    > };
    >
    > int boo(poly_base* p, int i, int j)
    > {
    > return p->foo(i,j);
    >
    > }
    >
    > int main()
    > {
    > poly_a a;
    > poly_b b;
    > poly_base* pa = &a;
    > poly_base* pb = &b;
    >
    > std::vector<poly_base*> plist;
    > plist.push_back(pa);
    > plist.push_back(pb);
    >
    > int v = 0;
    > for(std::vector<poly_base*>::iterator it = plist.begin();
    > it != plist.end();
    > ++it)
    > {
    > v += boo((*it),10,20);
    > }
    > return 0;
    >
    > }
    >
    > I was wondering how would one go about defining a container
    > of crtp_base's similar to the definition of the vector above
    > using the below structures.


    You can't since anything derived from crtp_base<crtp_a> is_not_a
    crtp_base<crtp_b>.

    >
    > Is it even possible without using an interface that is abstract?
    >
    > template <typename T>
    > class crtp_base
    > {
    > public: int foo(int i, int j) { return static_cast<T*>(this)-
    >
    > >foo(i,j); }

    > };
    >
    > class crtp_a : public crtp_base<crtp_a>
    > {
    > public: int foo(int i, int j) { return i + j; }
    >
    > };
    >
    > class crtp_b : public crtp_base<crtp_b>
    > {
    > public: int foo(int i, int j) { return i * j; }
    >
    > };
    >
    > template<typename T>
    > int boo(crtp_base<T>* p, int i, int j)
    > {
    > return p->foo(i,j);
    >
    > }
    >
    > int main()
    > {
    > crtp_a a;
    > crtp_b b;
    > crtp_base<crtp_a>* pa = &a;
    > crtp_base<crtp_b>* pb = &b;
    > boo(pa,10,20);
    > boo(pb,10,20);
    > return 0;
    >
    > }
    >
    > Any help would be much appreciated.
    >
    > Arash Partow
    > __________________________________________________
    > Be one who knows what they don't know,
    > Instead of being one who knows not what they don't know,
    > Thinking they know everything about all things.http://www.partow.net
     
    Salt_Peter, May 15, 2007
    #2
    1. Advertising

  3. Arash Partow

    Axter Guest

    On May 14, 7:10 pm, Arash Partow <> wrote:
    > Hi all,
    >
    > I've got a question related to emulating aspects of polymorphism
    > with CRTP. Below is a typical polymorphic class hierarchy with
    > a definition of a "somewhat" heterogeneous container of objects.
    >
    > class poly_base
    > {
    > public: virtual int foo(int i, int j) = 0;
    >
    > };
    >
    > class poly_a : public poly_base
    > {
    > public: int foo(int i, int j) { return i + j; }
    >
    > };
    >
    > class poly_b : public poly_base
    > {
    > public: int foo(int i, int j) { return i * j; }
    >
    > };
    >
    > int boo(poly_base* p, int i, int j)
    > {
    > return p->foo(i,j);
    >
    > }
    >
    > int main()
    > {
    > poly_a a;
    > poly_b b;
    > poly_base* pa = &a;
    > poly_base* pb = &b;
    >
    > std::vector<poly_base*> plist;
    > plist.push_back(pa);
    > plist.push_back(pb);
    >
    > int v = 0;
    > for(std::vector<poly_base*>::iterator it = plist.begin();
    > it != plist.end();
    > ++it)
    > {
    > v += boo((*it),10,20);
    > }
    > return 0;
    >
    > }
    >
    > I was wondering how would one go about defining a container
    > of crtp_base's similar to the definition of the vector above
    > using the below structures.
    >
    > Is it even possible without using an interface that is abstract?
    >
    > template <typename T>
    > class crtp_base
    > {
    > public: int foo(int i, int j) { return static_cast<T*>(this)-
    >
    > >foo(i,j); }

    > };
    >
    > class crtp_a : public crtp_base<crtp_a>
    > {
    > public: int foo(int i, int j) { return i + j; }
    >
    > };
    >
    > class crtp_b : public crtp_base<crtp_b>
    > {
    > public: int foo(int i, int j) { return i * j; }
    >
    > };
    >
    > template<typename T>
    > int boo(crtp_base<T>* p, int i, int j)
    > {
    > return p->foo(i,j);
    >
    > }
    >
    > int main()
    > {
    > crtp_a a;
    > crtp_b b;
    > crtp_base<crtp_a>* pa = &a;
    > crtp_base<crtp_b>* pb = &b;
    > boo(pa,10,20);
    > boo(pb,10,20);
    > return 0;
    >
    > }
    >
    > Any help would be much appreciated.
    >
    > Arash Partow
    > __________________________________________________
    > Be one who knows what they don't know,
    > Instead of being one who knows not what they don't know,
    > Thinking they know everything about all things.http://www.partow.net


    Either you need to have a common base class, or you need to have types
    that have a common interface.

    See following example for Heterogeneous Containers that can store
    objects that have different base types, but have some type of common
    interface (function signature).

    http://code.axter.com/HeterogeneousContainer1.cpp
    http://code.axter.com/HeterogeneousContainer2.cpp
    http://code.axter.com/HeterogeneousContainer3.cpp
     
    Axter, May 15, 2007
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kj
    Replies:
    1
    Views:
    379
    Ashmodai
    Apr 15, 2004
  2. Mike
    Replies:
    3
    Views:
    490
  3. Jason
    Replies:
    0
    Views:
    414
    Jason
    Aug 21, 2003
  4. Replies:
    7
    Views:
    578
    Pete Becker
    Jan 25, 2008
  5. Sebastian Mach
    Replies:
    5
    Views:
    342
Loading...

Share This Page