0

您好,我正在编写一个显示/显示和基准测试不同图形的程序。图由节点和边组成......所以我的问题是我有两个模板类(模板),它们是所有派生类的基础

template <class Node>
class Edge
{
public:
    Edge() : startN(0), endN(0), price(0) {}
    Edge(Node *startN, Node *endN, int price) : startN(startN), endN(endN), price(price)
    {
        startN->toEdges.push_back(this); // PROBLEM HERE
        endN->fromEdges.push_back(this); // PROBLEM HERE
    }

    Node *startNode() const {
        return startN;
    }
    Node *endNode() const {
        return static_cast<Node *>(endN);
    }
    int getPrice() const {
        return price;
    }
    void setPrice(int price) {
        this->price = price;
    }

private:
    Node *startN;
    Node *endN;

    int price;
}; 


template<template<class> class EdgeTemplate >
class NodeBase
{
public:
    NodeBase() : nodeId(0), key(0), state(UNLABELED), prev(0) {}
    NodeBase(int id, int key) : nodeId(id), key(key), state(UNLABELED), prev(0) {}

    void addToEdges(EdgeTemplate<NodeBase> *edge) {
        toEdges.push_back(static_cast<EdgeTemplate<NodeBase> *>(edge));
    }

    int nodeId;
    int key;
    State state;
    NodeBase *prev; // prevous scanned

    QVector<EdgeTemplate<NodeBase> *> fromEdges; // start
    QVector<EdgeTemplate<NodeBase> *> toEdges; // end
};

另一个模板类中出现错误:

template <template<class> class EdgeTemplate, class Node>
class DijkstraAlgorithm {
...
QVector<EdgeTemplate<Node> *> Edges; // the problem for derived classes
...
};

铛:

error: cannot initialize a parameter of type 'Edge<NodeBase<Edge> > *' with an rvalue of type 'Edge<DNode> *'
        startN->addToEdges(this);
                           ^~~~

海合会:

error: no matching function for call to 'QVector<Edge<NodeBase<Edge> >*>::push_back(Edge<DNode>* const)'

所以据我了解,问题是派生类DNodeclass DNode : public NodeBase <Edge>)不能存储在基类型的硬币容器中NodeBase<Edge>......我试过强制转换它,但它没有用。

有人可以解释我做错了什么,我该如何解决?

4

1 回答 1

0

在查看模板时,继承关系船舶根本不重要。

struct B {};
struct D : B {};

template<typename T>
struct C {};

C<B> *c = new C<D>; // error C<D> is completely different and has no relationship to C<B>

// you might as well say:
float *f = new char[50];

考虑:

template<>
struct C<B> {
    int a,b,c;
    int foo() { return a+b+c;}
};

template<>
struct C<D> {
    std::string s;
    std::string bar();
};

C<B> *c = new C<D>; // pretend it works.
c->foo(); // C<D> doesn't have a,b or c and doesn't have a method foo...

也许 NodeBase 应该只将边缘类型作为模板参数而不是边缘模板。

template<typename Edge> struct NodeBase {
    QVector<Edge *> fromEdges;
};

然后 DNode 继承自NodeBase<Edge<DNode>>

可能有更好的方法,可能更直接地使用 CRTP,但如果不了解更多当前设计,就很难说。

于 2012-08-02T18:28:24.940 回答