Если все, что вас волнует, это исключительная безопасность этой операции:
v.reserve(v.size()+1); // reserve can throw, but that doesn't matter
v.push_back(new Foo); // new can throw, that doesn't matter either.
Вопрос о векторе, отвечающем за освобождение объектов, на которые указывает его содержимое, - отдельная вещь, я уверен, что вы получите много советов по этому поводу; -)
Редактировать: хм, я собирался процитировать стандарт, но на самом деле я не могу найти необходимую гарантию. То, что я ищу, это то, что push_back
не будет выбрасывать, если (а) он не должен перераспределить (что мы знаем, это не будет из-за емкости), или (b) конструктор T-бросков (который мы знаем этого не произойдет, поскольку T является типом указателя). Звучит разумно, но разумно! = Гарантировано.
Итак, если на этот вопрос нет положительного ответа:
Разрешено ли сгенерировать std :: vector :: push_back по любой причине, кроме неудачного перераспределения или построения?
этот код зависит от того, что реализация не делает ничего «творческого». Если это не так, ваше решение из вопроса может быть задано шаблоном:
template <typename T, typename Container>
void push_back_new(Container &c) {
auto_ptr<T> p(new T);
c.push_back(p.get());
p.release();
}
Использование тогда не слишком утомительно:
struct Bar : Foo { };
vector<Foo*> v;
push_back_new<Foo>(v);
push_back_new<Bar>(v);
Если это действительно заводская функция, а не new
, вы можете соответствующим образом изменить шаблон. Передача большого количества разных списков параметров в разных ситуациях будет затруднена.