【问题标题】:abstract map and vector in stlstl 中的抽象地图和矢量
【发布时间】:2012-12-21 08:29:26
【问题描述】:

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

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

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

abstract_map = map1 or map2 or map3

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

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

【问题讨论】:

  • 您需要完整说明地图的实际类型,以及键和值之间的关系(公共基础、转换运算符等),以便我们有机会了解您正在尝试什么以及为什么您认为多态是解决方案。
  • @MatthieuM。我编辑了问题
  • 您还需要在仿函数上键入擦除吗?这就是std::function 已经存在的目的。两种std::function 类型的类型有何不同?那里的签名应该是一样的。
  • @pmr 签名是相同的,但类有 map1 作为成员,如果我通过构造函数传递 map2,它会给我一个错误,说它们不匹配
  • @djWann 显而易见的解决方案是将map1 设为map&lt; CString, int, std::function&lt;...&gt; &gt;

标签: c++ stl map vector abstract-class


【解决方案1】:

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

你总是可以这样做的:

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;
};

【讨论】:

  • 目的是修改一个类,尽可能减少更改,以获得使用不同类型地图的灵活行为
  • @djWann 所以地图中的 T 总是一样的?
  • @djWann 我添加了一个与现有客户端保持兼容性的变体。
【解决方案2】:

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

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

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

【讨论】:

  • @djWann:具体取决于您要做什么。
【解决方案3】:

不仅在 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 接口。您可以在此处编写所需的任何虚拟、纯虚拟或非虚拟方法。

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

【讨论】:

  • BaseMap 不应该有地图实例。对于上述模式,基接口类应该是抽象的。
  • @Yakk 为什么不呢?这取决于您在不同的地图类上需要什么。如果他们都可以使用相同的std::map,那么放置它的正确位置可能就是基类。
  • @Yakk 啊,现在我看到他在我写完答案后改变了很多。
猜你喜欢
  • 2010-09-08
  • 2011-05-17
  • 1970-01-01
  • 2015-11-13
  • 2014-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-26
相关资源
最近更新 更多