1

如果我有三种类型的地图和矢量:

map1<CString, int>
map2<CString, int, std::function1>
map3<some_wrapper_of_CString, int, std::function2>

在 stl 中是否有一个抽象容器或一种方法来编写我自己的抽象容器,其唯一目的是进行多态性:

abstract_map = map1 或 map2 或 map3

我的课程包含我无法修改的 map1,因为它会使我的大学在工作中使用的其他课程崩溃。我想通过创建一个抽象地图来包装 map1 我可以传递 map2 和 3 而无需其他修改......

我希望这是有道理的......

4

3 回答 3

3

不,没有。当元素不能相互转换时,它的目的是什么?

你总是可以这样做:

containera c;
containerb c2(c.begin(), c.end());

这会将所有元素从一个容器转换为另一个容器。

如果您实际上有具有相同底层value_type的容器,则容器类型上的通常抽象是迭代器而不是抽象容器。

在您澄清您只需要对仿函数类型进行类型擦除之后:

class X {
  // constructor taking the full type
  X(const std::map<CString, int, std::function<bool(CString, int)>& x) : my_map(x) {}

  // constructor taking the default std::less
  X(const std::map<CString, int>& x) : my_map(x.begin(), x.end(), std::less<CString>()) {}

private:
  std::map<CString, int, std::function<bool(CString, int)> my_map;
};
于 2012-12-21T08:31:41.887 回答
2

在 stl 中是否有一个抽象容器或一种方法来编写我自己的抽象容器,其唯一目的是进行多态性

在标准 C++ 库中,没有。

模板和动态多态性不能很好地混合。

于 2012-12-21T08:31:17.003 回答
2

在 STL 中不仅没有抽象容器:您永远不应该从 STL 容器继承,因为它们的行为并非多态(例如,没有虚拟析构函数)。所以你必须寻找不同的解决方案。

在这种情况下,您必须支持组合而不是继承。您可以编写自己的包含 的抽象地图类std::map,例如:

template<typename T>
class BaseMap
{
  // Whatever you need here

private:

  std::map<T> internalMap;
}

然后根据需要从这个类继承:

template<typename T>
class Map1 : public BaseMap<T>
{
  // Specialise your class here
}

当然,BaseMap应该提供地图所需的接口,因为它不继承std::map接口。您可以在此处编写所需的任何虚拟、纯虚拟或非虚拟方法。

尽管您可能要问自己的第一个问题是:您真的需要不同的地图类吗?如果是这样,你真的需要它们是多态的吗?

于 2012-12-21T08:39:11.740 回答