11

我正在尝试创建一个通用容器类型来提供一个通用接口,并隐藏我正在使用的内部容器,因为它们可能会发生变化。

基本上我有返回项目集合的插件,我不希望插件知道我的代码正在使用的容器类型。

谁能指出我比下面的示例代码更好的方向?

template<class C, typename I>
class Container
{
 public:
 //...

    void push(const I& item)
    {
        if(typeid(C) == typeid(std::priority_queue<I>))
        {
           std::priority_queue<I>* container = (std::priority_queue<I>*)&_container;
           container->push(item);
        }
        if(typeid(C) == typeid(std::list<I>))
        {
           std::list<I>* container = (std::list<I>*)&_container;
           container->push_back(item);
        }
        else
        {
           //error!
        }
     };

  private:
     C _container;
 //...
}

谢谢

4

3 回答 3

7

我有返回项目集合的插件,我不希望插件知道我的代码正在使用的容器类型。

让您的插件提供beginend迭代器到他们的项目集合中,然后根据您认为合适的方式使用范围。

迭代器的最大优点是它们允许将数据的存储方式(容器)与数据的使用方式(算法;在您的情况下,使用插件数据的应用程序代码)完全解耦。

这样,您不必关心插件如何存储他们的数据,并且插件不必关心一旦他们将数据提供给您,您将如何处理他们的数据。

于 2010-12-31T07:28:48.570 回答
0

从上面的类开始,公开插件所需的最小接口。然后根据您要使用的容器来实现它。这称为容器适配器,它是 std::stack 的实现方式。

如果你真的需要一个以上的 STL 容器和模板的适配器,请查看 std::stack,它将展示如何做到这一点。

不要打开 typeid,你为什么想要那个?

顺便说一句,除非需要暴露容器本身,否则请遵循 James 的建议。

于 2010-12-31T07:32:09.167 回答
0

您知道,当您编写“通用接口”时,我确信您将展示一些 Java 风格的东西,其中包含一个抽象类和包装标准容器的子类。我很惊讶地看到一堆 typeid 调用......

但是,你为什么要这样做呢?大多数容器共享一个通用接口,借助 SFINAE 的强大功能,您甚至不必编写特殊代码!只需使用模板并直接调用该方法即可。

编辑:忘记了标准容器没有虚拟方法,因此无法dynamic_cast编辑。

于 2010-12-31T07:22:13.577 回答