这是我的问题:我编写了两个基类:Wire和CircuitComponent。两者几乎相似,足以派生出一个共同的父类(super class),但事实并非如此。 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)这行,因为thisTwoTypeMesh<Wire, CircuitComponent>类型(Wire的父类(super class)),但是join仅针对wire定义。

到目前为止,我最好的理论是我不应该继承子类,也许是typedef,但是我还没有设法使它起作用。

最佳答案

实际上,使代码编译的最小侵入方法实际上是使用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;

10-08 10:52