2013-05-14 3 views
1

Сначала давайте начнем с проблемы. У меня есть дерево, и я хочу сделать следующее:Обход ковариации контейнеров в C++/STL

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*> и dynamic_cast'ing каждого элемента.
  • Передача в std::vector<Base*>, проверка первого элемента через dynamic_cast и последующее использование static_cast для остальных.
  • Выполнение AddChildren шаблонная функция (я не мог придумать, как заставить ее работать, поскольку std::vector хранится в памяти, а затем AddChildren вызывается через некоторое время).

Я мог бы reinterpret_cast, но это опасно, как насчет Союза? Это опасно?

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

Любая помощь оценивается.

ответ

5

Что случилось с children_.insert(children_.end(), children.begin(), children.end())? Прежде чем вы начнете думать о всех видах приводов, не имеет ли смысл установить, что прямое решение будет представлять проблему производительности вообще?

+0

Благодарим за проверку на реальность. По какой-то причине я думал, что это не сработает (фактически не приступив к проверке), потому что лежащие в основе векторы были разных типов. Я не совсем понял итераторов. – gremwell

Смежные вопросы