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

gre*_*ell 1 c++ containers stl covariance c++11

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

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_ 
    }
};
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 完成并单独添加每个元素
  • 创建一个std::vector<Base*>要添加的新内容children_(除非编译器可以优化它?)
  • 传入a std::vector<Base*>,并动态构建每个元素.
  • 通过a std::vector<Base*>,通过a检查第一个元素dynamic_cast,然后使用static_cast其余元素.
  • 创建AddChildren一个模板化的函数(我想不出如何使它工作,因为std::vector存储起来,然后AddChildren稍后调用).

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

union DerivedBUnion {
    std::vector<Base*>     base_;
    std::vector<DerivedB*> derivedB_;
}
Run Code Online (Sandbox Code Playgroud)

任何帮助赞赏.

mic*_*ion 5

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