Ответ 1
Как 0x499602d2 правильно указано, fill
необходимо скопировать назначение из третьего аргумента. Поскольку ваш тип неявно является неготовным, вы не можете использовать fill
.
Вы могли бы использовать generate
для заполнения вашего вектора:
#include <vector>
#include <algorithm>
struct noncopyable
{
noncopyable() = default;
// make it noncopyable
noncopyable(noncopyable const&) = delete;
noncopyable& operator=(noncopyable const&) = delete;
// make it movable (thanks, gx_)
noncopyable(noncopyable&&) = default;
noncopyable& operator=(noncopyable&&) = default;
};
int main()
{
std::vector<noncopyable> vec(10);
std::generate(begin(vec), end(vec), []()->noncopyable{return {};});
}
Примечание: это работает только в том случае, если noncopyable
имеет не удаленный доступный конструктор перемещения. Однако, если у него нет такого ctor, вы не сможете использовать большую часть вектора (resize
требует MoveInsertable
, для которого требуется либо копирование, либо move-ctor).
Для g++ 4.8, чтобы использовать generate
, вам понадобится бесплатная функция. Я думаю, что ошибка.
#include <vector>
#include <algorithm>
struct noncopyable
{
noncopyable() = default;
noncopyable(noncopyable const&) = delete;
};
noncopyable free_func()
{ return {}; }
int main()
{
std::vector<noncopyable> vec;
std::generate(begin(vec), end(vec), free_func);
}
Еще один вопрос: если вы можете инициализировать свой вектор таким образом. Я бы сказал НЕТ. fill
и generate
не создают элементы, а переписывают (присваивают). То есть вам уже понадобится вектор с несколькими элементами, прежде чем вы сможете их использовать.
Простейшая версия для инициализации вектора с N построенными по умолчанию элементами заключается в использовании конструктора:
std::vector<noncopyable> vec(10);
Создает vector
с 10 созданными по умолчанию элементами. Единственное требование - noncopyable
- DefaultConstructible (по существу, он должен иметь конструктор по умолчанию).
Если ваш тип не подлежит копированию и недоступен, вы не можете использовать его напрямую (или как элемент данных) для хранения его внутри vector
(*). Чтобы сделать класс C
movable, который содержит не подлежащий копированию, неподвижный тип X
, вам нужно сохранить X
в качестве указателя:
(*) Ну, вы можете, но вы не можете изменять размер вектора, вы не можете вставлять и т.д.
struct nocopies_nomoves
{
nocopies_nomoves() = default;
nocopies_nomoves(nocopies_nomoves const&) = delete;
nocopies_nomoves& operator=(nocopies_nomoves const&) = delete;
// not required to be explicitly deleted:
nocopies_nomoves(nocopies_nomoves&&) = delete;
nocopies_nomoves& operator=(nocopies_nomoves&&) = delete;
};
#include <utility>
#include <memory>
class C
{
public:
C() : ptr( new nocopies_nomoves() ) {} // make_unique in C++1y
// I don't think you need to explicitly define those as defaulted;
// at least not if you don't declare ANY of the copy/move ctors, assignment ops
// and dtor
C(C&& rhs) = default;
C& operator=(C&& rhs) = default;
~C() = default;
// not required to be explicitly deleted:
C(C const&) = delete;
C& operator=(C const&) = delete;
private:
std::unique_ptr<nocopies_nomoves> ptr;
};
Теперь вы можете создать vector<C>
и использовать его (например, resize
, insert
,...)
#include <vector>
#include <algorithm>
static C generate_C()
{
return {};
}
int main()
{
std::vector<C> vec(10);
// note: futile statement below; overwrites the 10 default-constructed
// elements
std::generate(begin(vec), end(vec), generate_C);
}