将列表<a *>转换为列表<b *>,其中B继承A </b *> </a *>

时间:2014-07-16 09:00:43

标签: c++ templates stl casting containers

我有一个功能

void doSomething(list<A*> list1, list<A*> list2)

和班级

class B : A  
class C : A

是否可以直接调用我的函数

void doSomething(list<B*> listOfB, list<C*> listOfC)

或者我必须像

那样手动换行
void doSomething(list<B*> listOfB, list<C*> listOfC) {
  list<A*> l1;
  list<A*> l2;

  for (B* b : listOfB)
    l1.insert(b);

  for (C* c : listOfC)
    l2.insert(c);

  doSomething(l1, l2); //calling the function taking supertype
}

我尝试将list<B*>转换为list<A*>失败,我的猜测是由于模板特化,编译器认为list<B*>list<A*>无关,但B继承A.

有人可以确认一下,或者以不同的方式来管理这个问题吗?

1 个答案:

答案 0 :(得分:4)

你的直觉(和juanchopanza的评论)是正确的 - 列表是完全不相关的类型。

选项包括:

  1. 首先在任何地方使用list<A*>,即使您知道动态类型为B*C*
  2. list<A*>上编写一个包装器,该包装器转换为正确的动态类型 - 这相当于Java泛型中的(un)装箱行为
  3. 重新编写doSomething作为函数模板,其唯一约束是类型可转换

    template <typename Sequence1, typename Sequence2>
    void doSomething(Sequence1 &x, Sequence2 &y) {
      // require only that *x.begin() is convertible with *y.begin(), etc.
    }
    

    我也同意Kerrek的建议,即应该使用迭代器,但这并没有显着改变类型要求 - 你只需要两个迭代器类型的参数而不是两个容器类型的参数