I am writing this in a new thread to alert that I found a solution to
the problem mentioned here:
http://groups.google.com/group/comp....70afaa089fd5b8
and to avoid this topic getting lost before people interested in the
problem notice it.
The important tricks to the solution are two:
1) make the custom classes take a TEMPLATE argument which defines their
BASE class
2) EMBED the custom classes in a "Traits" class which is passed as
template argument to the Mesh class instead of passing them directly
(1) makes your class being a derived class that takes a generic base
class which doesn't have to be explicitly given. (2) allows you to pass
the custom classes as template arguments to the Mesh class without
immediately specifying their own template argument (i.e. their base
class).
The final custom classes are fully defined and instantiated only inside
the Mesh class which in turn contains nested classes that become base
classes of custom classes. Just before the definition of these nested
(i.e. base) classes, there is a forward declaration of final classes
which gives template arguments to custom classes and again before it a
forward declaration of base classes.
Here is a partial implementation of the solution, showing the type-safe
inter-linking of custom Vertex and Edge classes
//Mesh.h
////////////////////////////////////////////////////////
template <class MeshTraits>
class Mesh {
public:
//forward declaration of base classes
class BaseVertex;
class BaseEdge;
//forward declaration of final classes (using base classes as
template arguments)
typedef typename MeshTraits :: template Vertex<BaseVertexVertex;
typedef typename MeshTraits :: template Edge<BaseEdgeEdge;
//nested base classes follow
class BaseVertex {
public:
Edge *edge;
};
class BaseEdge {
public:
Vertex *vert;
};
};
//MeshTest.cpp
////////////////////////////////////////////////////////
#include <stdio.h>
class MyMeshTraits {
public:
//Vertex class taking a generic base class
template<class Baseclass Vertex : public Base {
public:
//custom member
int a;
//function using BaseVertex edge pointer to
//get to edge's custom member
void printEdgeB() {
printf("edge's b = %d\n", Base::edge->b);
}
};
//Edge class taking a generic base class
template<class Baseclass Edge : public Base {
public:
//custom member
int b;
//function using BaseEdge vert pointer to
//get to vert's custom member
void printVertA() {
printf("vert's a = %d\n", Base::vert->a);
}
};
};
int main(int argc, char **argv) {
//a little code to test things
Mesh<MyMeshTraits>::Vertex vert;
Mesh<MyMeshTraits>::Edge edge;
vert.a = 20;
edge.b = 40;
vert.edge = &edge;
edge.vert = |
vert.printEdgeB();
edge.printVertA();
};