具有通用模板基类型的 STL 容器,接受派生类型

Posted

技术标签:

【中文标题】具有通用模板基类型的 STL 容器,接受派生类型【英文标题】:STL Container with generic templated base type, accepting derived types 【发布时间】:2016-04-07 02:48:41 【问题描述】:

我想创建一个带有 Base 类型的 EventHandler 的地图,但在该地图中插入几个派生的 EventHandler,如下所示:

std::unordered_map<int, EventHandler<Base>*> maap;
EventHandler<Derived>* e1 = new EventHandler<Derived>();
maap.emplace(std::make_pair(1, e1));

这对于简单对象的指针来说是可能的,但是在这里,EventHandler 是一个模板化的对象,所以编译器正在忙于转换。 如果我能做类似的事情就好了

template <class T>
std::unordered_map<int, EventHandler<T>> maap;

但这也不起作用......有什么想法吗?

【问题讨论】:

我想到的唯一选择是编写一个可以容纳所有 EventHandler 类型并使用映射的变体类。例如。你可以为此使用 boost 变体 【参考方案1】:

我想出了一个解决方案。我创建了一个空的抽象类 IEventHandler 并从该类继承了 EventHandler。然后我制作了一张 IEventHandler* 的地图,它现在似乎工作正常。它可以添加任何类型的 EventHandler。我现在需要找到一种方法来确保 IEventHandler 仅由 EventHandler 继承,并且它仅属于正确的 T 类型。

2 个小更新: 我使用了 static_cast 来调用 EventHandlers 方法,并且因为它正在转换为指针,所以没有额外的复制构造函数称为 ^_^ 我通过给它一个私有的析构函数和友好的 EventHandler 来限制谁可以从 IEventHandler 派生

【讨论】:

I need to now find a way to make sure IEventHandler is only inherited by EventHandler为什么要施加这样的限制? 控制预期用途。但我意识到这毕竟不是一个好的解决方案。我仍然需要 IEventHandler 有一个接受 类型参数的函数,这又导致了我的老问题。如果我发现了什么,我会发布更新。 我最终只是做了一个 static_cast 来将 IEventHandler 转换为 EventHandler。我觉得很脏。 您在答案中的解决方案很好。然后,您只需像这样从基类继承:template &lt;typename T&gt; class HandlerOne : public IEventHandler 并具有预期的行为。

以上是关于具有通用模板基类型的 STL 容器,接受派生类型的主要内容,如果未能解决你的问题,请参考以下文章

STL 容器类型作为模板参数

C ++从具有嵌套类的接口派生

具有 std::array 大小类型的派生模板类

C++ STL与迭代器

STL概念

使用多态性是在一个容器下存储不同数据类型的好方法吗?