5

我理解为什么 成员模板函数不能是 virtual,但我不确定最好的解决方法是什么。

我有一些类似的代码:

struct Entity
{
    template<typename It>
    virtual It GetChildren(It it) { return it; }
};

struct Person : public Entity
{
    template<typename It>
    virtual It GetChildren(It it) { *it++ = "Joe"; }
};

struct Node : public Entity
{
    Node left, right;
    const char *GetName() { return "dummy"; }

    template<typename It>
    virtual It GetChildren(It it)
    {
        *it++ = left.GetName();
        *it++ = right.GetName();
        return it;
    }
};

显然,我需要动态调度。但鉴于这些类实际上非常大,我不想模板化整个类。而且我仍然想支持任何类型的迭代器。

实现这一目标的最佳方法是什么?

4

3 回答 3

3

如果支持任何类型的迭代器是您唯一想要的,您可以使用使用类型擦除的迭代器。我认为any_iterator在 Boost Sandbox/Vault 或 Adob​​e Labs 或其中之一的某个地方实现了。这是谷歌的第一个结果:

http://thbecker.net/free_software_utilities/type_erasure_for_cpp_iterators/any_iterator.html

于 2011-11-11T21:01:03.453 回答
2

由于您不想模板化整个类,并且不想使用带有类型擦除的迭代器,唯一的解决方案是编写自己的迭代器。

顺便说一句,你的例子看起来很奇怪。也许你可以看看如何改进设计,这会让你的问题消失。

于 2011-11-11T21:11:47.087 回答
1

您不想笼统地“支持任何类型的迭代器”。

您希望满足 STL Container 要求以提供用户可以普遍支持的迭代器。创建一个迭代器,然后为您的容器提供一个迭代器 typedef:

class Entity_Iterator {
public:
    Entity_Iterator operator++() { /* et cetera */ }
    Entity& operator*() const { /* et cetera */ }
private:
    Entity* entity_ptr_;
    // et cetera
}

class Entity_Container {
public:
    typedef Entity_Iterator iterator;
    iterator begin() const { /* et cetera */ }
    iterator end() const  { /* et cetera */ }
private:
    Entity* head_;
    // et cetera
}

现在用户可以遵循 STL 容器约定来使用您的容器,并且您也可以将 STL 算法应用于您的容器:

Entity_Container x;
Entity_Container::iterator i = x.begin();
i->GetName();

编辑添加链接:

http://www.sgi.com/tech/stl/Container.html

编辑

我正在尝试通过 Google 搜索到一个完整的 C++ 代码存根模板的链接,以实现我记得曾经见过的 STL 容器,但我发现 Google STL 模板非常困难。

编辑

这样做,您将能够将您的容器编写为一个树结构,该结构可以包含从具有虚拟方法的 Entity 继承的异构类型,这看起来就是您正在尝试做的事情?

或者也许不是?

于 2011-11-11T21:50:32.910 回答