c ++相互依赖的类模板,指针转换派生类

时间:2012-08-02 18:02:03

标签: c++ qt templates gcc clang

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

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
...
};

Clang:

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)'

据我所知,问题是派生类DNodeclass DNode : public NodeBase <Edge>)无法存储在基类型NodeBase<Edge>的投币器中...我已尝试过投射但它没有用。

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

1 个答案:

答案 0 :(得分: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,但是如果不了解更多当前的设计,很难说。