让虚方法接受任何 Qt 容器类型作为输入参数

Let virtual method accept any Qt container type as input paramter

我有两个图表 类:DirectedGraphDirectedBreakableGraphDirectedBreakableGraph 继承自 DirectedGraph,并提供暂时 断开 边的能力,这意味着不应遍历它们,即使它们仍然是图的一部分。这样可以暂时解决图中的循环

DirectedGraph有一个DFS(深度优先搜索)遍历图的方法。此方法是 virtual,因此 DirectedBreakableGraph 可以有自己的实现,忽略断边。

我希望能够通过将起始节点集合传递给 DFS 来指定深度优先搜索应该从哪个节点开始。现在,我不想限制包含起始节点的集合的类型。例如,它可以是 QVectorQSet.

由于方法是虚拟的,所以它不能同时是模板。那么是否不可能让它同时接受 QVectorQSet 作为输入参数?也许除了使用 type erasure?

class DirectedGraph {
public:
    // DFS should accept either QVector or QSet.
    virtual void DFS(QVector<Node *> const &StartNodes) const;
};

class DirectedBreakableGraph : public DirectedGraph {
public:
    // DFS should accept either QVector or QSet.
    void DFS(QVector<Node *> const &StartNodes) const override;
};

使用类型擦除,您可能会执行以下操作:

template <typename T>
struct IGenerator
{
    virtual ~IGenerator() = default;
    virtual void reset() = 0;
    virtual const T* value_and_next() = 0;
};

template <typename Container>
struct Generator : IGenerator<typename Container::value_type>
{
    Generator(const Container& container) : container(container), it(container.begin()) {}
    virtual void reset() override { it = container.begin(); }
    virtual const typename Container::value_type* value_and_next() override
    {
        if (it == container) { return nullptr; }
        return &(*it++);
    }

    const Container& container;
    typename Container::const_iterator it;
};


class DirectedGraph {
public:
    // DFS should accept either QVector or QSet.
    virtual void DFS(IGenerator<Node *> const &StartNodes) const
    {
        while (const auto* p = StartNodes.value_and_next()) {
            Node* node = *p;
            // ...
        }
    }
};

然后你可能会做

directGraph.DFS(Generator{myVector});
directGraph.DFS(Generator{mySet});