这是我的问题:我写了两个基类:Wire和CircuitComponent。这两者几乎相似,足以衍生出一个共同的超类,但不是。 Wire只能与CircuitComponent连接,而CircuitComponent只能与wire连接。除了类型之外,实现是相同的,所以我自然认为模板就是答案。
这是模板,我有一个派生自TwoTypeMesh<Wire, CircuitComponent>
的Wire类和一个派生自TwoTypeMesh<CircuitComponent, Wire>
的CircuitComponent类:
template <class thisType, class otherType>
class TwoTypeMesh {
std::set<otherType *> neighbors;
public:
void join(otherType * n){
if (neighbors.find(n) != neighbors.end()) {
return;
} else {
neighbors.insert(n);
n->join(this);
}
}
void disconnect(otherType * n){
if (neighbors.find(n) == neighbors.end()) {
return;
} else {
neighbors.erase(n);
n->disconnect(this);
}
}
};
问题是我无法将其编译,它抱怨n->join(this)
因为this
的行是TwoTypeMesh<Wire, CircuitComponent>
类型(Wire
的超类)但是join
仅针对wire
定义。
到目前为止,我最好的理论是我不应该是子类,也许是typedef,但我还没有设法让它工作。
答案 0 :(得分:1)
将join()移到类外:
void join(Wire &w, CircuitComponent &j);
void join(CircuitComponent &j, Wire &w);
您可能需要使该类的函数成为访问私有数据成员的朋友。
答案 1 :(得分:1)
使代码编译的微创方式确实是使用typedef,tag classes或简单的Enumerations:
enum MeshType { MeshTypeWire, MeshTypeCircuitComponent };
template <MeshType thisType>
class TwoTypeMesh {
// calculate 'otherType' from 'thisType' (prevents usage mistakes):
static const MeshType otherType =
thisType == MeshTypeWire ? MeshTypeCircuitComponent :
/* else */ MeshTypeWire ;
std::set< TypeTwoMesh<otherType> *> neighbors;
public:
void join(TypeTwoMesh<otherType> * n){
if (neighbors.find(n) != neighbors.end()) {
return;
} else {
neighbors.insert(n);
n->join(this);
}
}
void disconnect(TypeTwoMesh<otherType> * n){
if (neighbors.find(n) == neighbors.end()) {
return;
} else {
neighbors.erase(n);
n->disconnect(this);
}
}
};
typedef TwoTypeMesh<MeshTypeWire> Wire;
typedef TwoTypeMesh<CircuitComponent> CircuitComponent;
答案 2 :(得分:0)
要解决您的特定编译错误,您应该可以在this
的调用中将static_cast thisType*
改为n->join
。
您似乎意外地重新发明了CRTP:一个模板基类,它将派生类作为模板参数。只是不要在除T之外的任何类中继承TwoTypeMesh<T,U>
,并使TwoTypeMesh
的构造函数受到保护以防止直接实例化。然后,您可以确定TwoTypeMesh<T, something>
的任何实例都是T
实例(或T
的派生类)的基类子对象,因此static_cast
到{ {1}}有效。