Is implicitly deleted because the default definition would be ill formed

As 0x499602d2 correctly pointed out, fill needs to copy-assign from the third argument. As your type implicitly is noncopyable, you cannot use fill.

You could, however, use generate to fill your vector:

#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 {};}); }

Note: this only works if noncopyable has a non-deleted, accessible move constructor. However, if it does not have such a ctor, you won’t be able to use much of the vector (resize requires MoveInsertable, which requires either a copy- or move-ctor).

For g++4.8, to use generate, you’ll need a free function. I think that’s a bug.

#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); }

Yet another question is if you can initialize your vector like that. I’d say NO. fill and generate do not construct elements, but overwrite (assign). That is, you’ll already need to have a vector with multiple elements before you can use them.

The easiest version to initialize a vector with N default-constructed elements is to use the constructor:

std::vector<noncopyable> vec(10);

Creates a vector with 10 default-constructed elements. The only requirement is that noncopyable is DefaultConstructible (essentially, it must have a default constructor).

If your type is noncopyable AND nonmovable, you cannot use it directly (or as a data member) to store it inside a vector(*). To make a class C movable, which contains a noncopyable, nonmovable type X, you need to store X as a pointer:

(*) Well, you can, but you cannot resize the vector, you cannot insert etc.

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; };

Now you can create a vector<C> and use it (e.g. 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); }

Related Posts