我正在尝试创建一个通用容器类型来提供单个公共接口,以及隐藏我正在使用的内部容器,因为它们可能会发生变化。
基本上我有插件返回项目集合,我不希望插件知道我的代码正在使用的容器类型。
有人能指出我比下面的示例代码更好的方向吗?
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;
//...
}
由于
答案 0 :(得分:7)
我有插件返回项目集合,我不希望插件知道我的代码正在使用的容器类型。
让您的插件将begin
和end
迭代器提供到其项目集合中,然后根据需要使用该范围。
迭代器的最大优点是它们允许完全解耦数据的存储方式(容器)与数据的使用方式(算法;在您的情况下,是消耗插件数据的应用程序代码)。
通过这种方式,您无需关心插件如何存储数据,并且插件在提供给您后无需关心您对数据执行的操作。
答案 1 :(得分:0)
您知道,当您编写“通用接口”时,我确信您将使用抽象类和包装标准容器的子类来展示Java样式。我很惊讶地看到一堆打字电话......
但是,你为什么要这样做呢?大多数容器共享一个通用接口,并且凭借SFINAE的强大功能,您甚至不必编写特殊代码!只需使用模板并直接调用该方法。
编辑:忘记标准容器没有虚拟方法,因此不能dynamic_cast
。
答案 2 :(得分:0)
从上面的类开始,展示插件所需的最小接口。然后根据您要使用的容器实现它。这称为容器适配器,它是如何实现std :: stack的。
如果你真的需要适配器以供一个以上的STL容器使用模板,看看std :: stack,它将显示如何做到这一点。
不要打开typeid,为什么要这样?
顺便说一下,除非需要暴露容器本身,否则请继续使用James建议的内容。