C ++ 11 — Обход контейнерной ковариации в 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_;
}

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

1

Решение

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

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]