在C ++ / STL中解决容器协方差问题

时间:2013-05-14 05:19:33

标签: c++ c++11 stl containers covariance

首先让我们从问题开始。我有一棵树,我想做以下事情:

class Base {
    std::vector<Base*> children_;
};

class DerivedA : public Base {
    //adds some members
};

class DerivedB : public Base {
    void AddChildren(std::vector<DerivedA*> children, int position) {
        //Do stuff based on the fact that it's a DerivedA
        //Add to the list of children_ 
    }
    void AddChildren(std::vector<DerivedB*> children, int position) {
        //Do stuff based on the fact that it's a DerivedB
        //Add to the list of children_ 
    }
};

我遇到了容器协方差问题 - std::vector<DerivedA*>(或DerivedB*)与std::vector<Base*>不同。但与此同时,我不想在AddChildren中创建一个全新的向量,只是为了将它们添加到std::vector<Base*>

那么有没有一种方法可以将向量直接添加到children_列表而不会产生太多的性能开销?

我考虑过的事情并不是特别喜欢:

  • 单独添加每个元素
  • 创建一个新的std::vector<Base*>以添加到children_(除非编译器能够优化它吗?)
  • 传递std::vector<Base*>,并动态广播每个元素。
  • 传入std::vector<Base*>,通过dynamic_cast检查第一个元素,然后使用static_cast
  • 使AddChildren成为模板化函数(由于std::vector被存储起来,我无法想到如何使其工作,然后稍后会调用AddChildren。)

我可以重新解释广播,但这很危险,联盟怎么样?这有危险吗?

union DerivedBUnion {
    std::vector<Base*>     base_;
    std::vector<DerivedB*> derivedB_;
}

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:5)

children_.insert(children_.end(), children.begin(), children.end())出了什么问题?在考虑各种演员表之前,确定直截了当的解决方案会造成性能问题是不是有意义?