Вы можете собрать свой собственный итератор, который создает экземпляры по умолчанию при разыменовании.Это значения, которые позволяют создавать в векторе только для перемещения типы.Используйте подсчет экземпляров такого итератора для вызова std::vector::insert
.Вот пример, который, вероятно, не соответствует стандарту, но работает.
template <class T>
class DefaultCtorInputIt {
public:
DefaultCtorInputIt(size_t n) : n(n) {}
using value_type = T;
using reference = T;
using pointer = T;
using iterator_category = std::input_iterator_tag ;
using difference_type = int;
using Self = DefaultCtorInputIt; // save typing (below)
value_type operator *() { return T(); }
Self& operator ++() { ++n; return *this; }
friend bool operator == (const Self& lhs, const Self& rhs) {
return lhs.n == rhs.n;
}
friend bool operator != (const Self& lhs, const Self& rhs) {
return !(lhs == rhs);
}
private:
size_t n;
};
Таким образом, вы можете
std::vector<std::unique_ptr<int>> v;
// Fill v with some values...
using NullUPtr =DefaultCtorInputIt<std::unique_ptr<int>>; // save typing
// Insert 10 default constructed instances at desired position:
v.insert(v.begin() + 42, NullUPtr(0), NullUPtr(10));
Обратите внимание, что для того, чтобы это было максимально эффективно, вы, вероятно, должны сделатьубедитесь, что приведенный выше итератор квалифицируется как итератор с произвольным доступом, так что размер диапазона [NullUPtr(0), NullUPtr(10))
может быть вычислен с O (1) заранее, чтобы выделить память только один раз.При создании собственного типа итератора также стоит взглянуть на Повысить фасад итератора .