c++相互依赖的类模板,指针投射派生类

c++ interdependent class templates, pointer casting derived classes

本文关键字:指针 派生 依赖 c++      更新时间:2023-10-16

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

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>的共容器中。。。我试过选角,但没用。

有人能解释一下我做错了什么吗?我该如何解决这个问题?

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

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,但很难说不看到更多当前的设计。