【问题标题】:Casting containers C++ [duplicate]铸造容器C ++ [重复]
【发布时间】:2011-10-05 14:33:01
【问题描述】:

可能重复:
Is it ok to cast a STL container with Base type to Derived type?

这应该是一个快速的问题...如果我有一个容器,比如一个基类的 STL 列表,是否可以将整个容器转换为一种子类?例如

[A inherits from base class B]

list<B*> list1;
list1.push_back(new A());

list<A*> list2 = list1;

编译器在抱怨:“conversion from std::vector&lt;B*, std:allocator&lt;B*&gt; &gt;' to non-scalar type 'std::vector&lt;Bar*, ...&gt;' requested.

这可能吗,还是我搞砸了?

【问题讨论】:

标签: c++ oop


【解决方案1】:

没有。 std::list&lt;T&gt;std::list&lt;U&gt; 是完全不同的、不兼容的类型,如果 std::is_same&lt;T,U&gt;::valuefalse,即如果类型参数 TU 不一样。

使用std::transform 并在回调中进行适当的转换。

【讨论】:

  • 这不会(通常)安全,因为 OP 正在从父类分配给子类指针。
【解决方案2】:

不,这不可能直接实现,因为具有不同模板类型的lists 是完全不相关的容器。

如果您知道list1 中的所有项目实际上都是A 的子类,那么只需让list1 预先包含它们。如果您知道它们都是子类,那么您想要进行的转换是非法的。

真的想在这里做什么?

【讨论】:

【解决方案3】:

更安全的方法是使用 std::transform。

但是,由于在 std::list 的实现中,T=A* 或 T=B* 的行为方式相同(两者具有相同的大小),因此列表具有与列表相同的内部结构。所以可以做以下技巧:

list<B*> list2 = *( reinterpret_cast< list<B*>* >(&list1) );

注意: 我的回答是信息性的,请坚持使用 std::transform 方法。另外,我用 GCC 测试了它并且它可以工作,但我不确定在其他 STDC++ 实现中列表的行为方式是否相同。

【讨论】:

  • +1 表示这种高度不安全但通常(在某些限制条件下)可行的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-26
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-26
  • 1970-01-01
相关资源
最近更新 更多