C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Heterogeneous containers with CRTP

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Guest






PostPosted: Mon May 14, 2007 7:40 pm    Post subject: Heterogeneous containers with CRTP Reply with quote



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)-
Quote:
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


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Lance Diduck
Guest





PostPosted: Tue May 15, 2007 12:38 am    Post subject: Re: Heterogeneous containers with CRTP Reply with quote



On May 14, 3:40 pm, par...@gmail.com wrote:
Quote:
Hi all,

Is it even possible without using an interface that is abstract?
Yes it is possible, however, you cannot use STL containers to do so.

STL containers require copies of homogenous types. However, this is a
requirement of STL containers, not collections in general.
In fact, many pre -STL "container libraries" allowed heterogenous
elements. The trick was to define a "node" class that you inherited
your to be contained class from. So you might have something like
this

struct Node{
//likely a node of a doubly linked list
private:
Node* prev();
Node* next()
friend class NodeCollection;
//data
};
class NodeIterator{
//make possible iterating through Nodes

};
template <typename T>
class crtp_base: public Node
{
public: int foo(int i, int j)
{ return static_cast<T*>(this)- >foo(i,j); }
};
class NodeCollection{
public:
void insert(Node&);
void remove(Node&);
NodeIterator begin();
};
Note that syntatically this is very similar to a STL container, say
std::list<Node>. The difference is two fold:
1) The object to be contained is the one implements the node, so there
are no container allocators, nor locks, nor any sort of resource
management. This makes it mush easier to make the container binary
compatible, that is , it does not expose implementation choices such
as memory managers.
2) The object to be contained does not require a copy constructor,
nor a default. Again this makes it attractive for use when you are
using virtual constructors (i.e. abstract object factories)

There are drawbacks:
1) user must keep up with the types actually contained.
2) each object can be contained only once per inherited node

In most cases, the drawbacks far outweigh the advantages. However,
there are a couple of places I have used this technique.

Lance


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Sebastian Redl
Guest





PostPosted: Tue May 15, 2007 12:42 am    Post subject: Re: Heterogeneous containers with CRTP Reply with quote



On Mon, 14 May 2007 partow (AT) gmail (DOT) com wrote:

Quote:
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);
}

No, it's not possible. crtp_base<crtp_a> and crtp_base<crtp_b> are
completely distinct types. That they are instantiated from the same
template is irrelevant.

What you can do is introduce another, non-template base that crtp_base
derives from:

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

template <typename Derived>
class crtp_base : public real_base
{
};


Of course, that rather loses you the advantage of using CRTP in the first
place.

Sebastian Redl

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Lars Jordan
Guest





PostPosted: Tue May 15, 2007 10:56 pm    Post subject: Re: Heterogeneous containers with CRTP Reply with quote

Roman.Perepelitsa (AT) gmail (DOT) com wrote:
Quote:

You can use tuple instead of vector. Then you can call 'boo' for each
element of tuple in pseudo recursive template function (consider using
boost::fusion instead of hand-crafted solution).

I think the hard limit of this approach is the compiler limit for
recursive template instantiations which directly limits the number of
elements in your "container". I don't know concrete numbers but at
first glance I'd consider this at least to be an issue. The fact that
this compiler limit might not be equal between different compilers
renders the approach non-portable. This makes it a solution only to a
limited number of use cases. Next issue: elements are restricted to
reside at locations with the exact element type which means that
moving elements around freely is not possible. Worst case: The
elements in the "container" differ all in type - then each element can
be placed at exactly one position. Again a limitation in applicability.

Do you know of any way to overcome these limitations?


bests,

Lars


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Mathias Gaunard
Guest





PostPosted: Wed May 16, 2007 4:20 am    Post subject: Re: Heterogeneous containers with CRTP Reply with quote

On May 16, 12:56 am, Lars Jordan <lars.jor...@informatik.tu-
chemnitz.de> wrote:
Quote:
Roman.Perepeli...@gmail.com wrote:

You can use tuple instead of vector. Then you can call 'boo' for each
element of tuple in pseudo recursive template function (consider using
boost::fusion instead of hand-crafted solution).

I think the hard limit of this approach is the compiler limit for
recursive template instantiations which directly limits the number of
elements in your "container". I don't know concrete numbers but at
first glance I'd consider this at least to be an issue.

That's configurable on GCC at least. And by default it is 500, which
is already pretty big.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.