0

こんにちは、さまざまなグラフを表示/表示してベンチマークするプログラムを書いています。グラフはノードとエッジで構成されています...したがって、私の問題は、すべての派生クラスのベースである 2 つのテンプレート クラス (テンプレート) があることです。

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);
                           ^~~~

GCC:

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

問題は、派生クラスDNode( class 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 に答える