【问题标题】:Getting around container covariance in C++/STL在 C++/STL 中解决容器协方差
【发布时间】:2013-05-14 05:19:33
【问题描述】:

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

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&lt;DerivedA*&gt;(或 DerivedB*)与 std::vector&lt;Base*&gt; 不同。但同时我不想在AddChildren 中创建一个全新的向量,只是为了将它们添加到std::vector&lt;Base*&gt;

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

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

  • 逐个检查并添加每个元素
  • 创建一个新的 std::vector&lt;Base*&gt; 以添加到 children_(除非编译器可以优化它?)
  • 传入std::vector&lt;Base*&gt;,并对每个元素进行动态转换。
  • 传入std::vector&lt;Base*&gt;,通过dynamic_cast 检查第一个元素,然后使用static_cast 进行其余部分。
  • 使AddChildren 成为模板函数(我想不出如何使它工作,因为std::vector 被存储起来,然后稍后调用AddChildren)。

我可以 reinterpret_cast 但这很危险,Union 呢?这很危险吗?

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

任何帮助表示赞赏。

【问题讨论】:

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


    【解决方案1】:

    children_.insert(children_.end(), children.begin(), children.end()) 有什么问题?在考虑各种类型转换之前,确定简单的解决方案会带来性能问题难道不是很有意义吗?

    【讨论】:

    • 感谢您的实际检查。出于某种原因,我认为这行不通(实际上没有进行检查),因为底层向量属于不同类型。我没有完全理解迭代器。
    猜你喜欢
    • 1970-01-01
    • 2017-08-23
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 2012-11-15
    相关资源
    最近更新 更多