C ++ идиома для динамического заполнения объектов и уничтожения при возврате - PullRequest
0 голосов
/ 18 июля 2011

Я использую C ++ 0x.

У меня есть функция call_third_party, которая получает список A*, преобразует его в список B*, затем передает этот списокB* в функцию third_party.После вызова third_party список B* больше не нужен.

Как следует из названия, я не могу контролировать third_party.

В настоящее время у меня есть что-то подобное.

void call_third_party(const vector<A*>& as) {
    vector<unique_ptr<B>> allocated_bs;
    vector<B*> bs;
    vector<A*>::iterator it;
    for (it = as.begin(); it < as.end(); it++) {
        unique_ptr<B> b(new B(*it));
        allocated_bs.push_back(b);
        bs.push_back(b.get());
    }
    third_party(bs);
}

На всякий случай, если это поможет.Вот конструктор B и подпись third_party.

void third_party(const vector<B*>& bs);
B(A* a);

Есть ли лучший идиоматический способ сделать это?

Ответы [ 4 ]

9 голосов
/ 18 июля 2011
void call_third_party(const vector<A*>& as)
{
   std::vector<B> b(as.begin(), as.end());
   std::vector<B*> bp(b.size());
   std::transform(b.begin(), b.end(), bp.begin(), [](B& b) { return &b; });
   third_party(bp);
}
3 голосов
/ 18 июля 2011

Будет

// change name to held_b or something?
vector<B> allocated_bs;
// ...
for(...) {
    auto emplaced = allocated_bs.emplace(allocated_bs.end(), *it);
    bs.push_back(&*emplaced);

возможно? Я не вижу необходимости в динамическом размещении.

0 голосов
/ 19 июля 2011

ИМХО, кажется, слишком много, чтобы выделить второй вектор только для указателей - шок ужас, почему бы не сделать это по старинке?

template <typename PtrContainer>
struct auto_delete
{
  ~auto_delete()
  {
    for(auto it = _cont.begin(); it != _cont.end(); ++it)
      delete *it;
  }
  PtrContainer& _cont;
};

void call_third_party(const vector<A*>& as)
{
  std::vector<B*> allocated_bs;
  allocated_bs.reserve(as.size());
  // this will take care of cleanup - irrespective of where the exit point is
  auto_delete<std::vector<B*>> dt = { allocated_bs }; 
  (void)dt;
  for(auto it = as.begin(); it != as.end(); ++it)
    allocated_bs.push_back(new B(*it));
  third_party(allocated_bs);
}
0 голосов
/ 18 июля 2011

Boost's ptr_vector может сделать это намного проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...