Reputation: 509
Recently I'm surprised at the fact std::unique_ptr
is acceptable for elements of STL containers, because I thought these elements are required to provide functions below(this page says the same):
But std::unique_ptr
is not copyable to make the pointer it holds owned by a single object, that contradicts the requirements above.
Has the standard changed the requirements? If so, what are the changes? Perhaps either movable objects or copyable ones are sufficient? I've searched the web whether the requirements has changed since C++11, but I can't find any page which helps me...
Upvotes: 27
Views: 4210
Reputation: 474406
Yes, there have been major changes to the requirements for standard library containers. It's hard to provide a comprehensive list (there were a lot), but here are some important ones:
std::vector
generally requires only that its members be MoveConstructible and MoveAssignable. There are many member functions of std::vector that impose more strict requirements. vector::push_back
requires Move or CopyConstructible (depending on whether you pass an rvalue or lvalue), but the new vector::emplace_back
only requires that there is an accessible constructor that takes the given parameters (in addition to the baseline requirement). Obviously any attempt to invoke the vector
's copy constructor/assignment will require that the type be CopyConstructible (ie: you can't copy a std::vector<unique_ptr>
).
Similarly, most other containers have reduced the restrictions on the type. They also have emplace
member functions that allow you to construct the members in-place, as well as l/rvalue insertion functions. Which means that you don't have to copy values in; you can move them in or construct them in-place.
None of the constructors or destructors are required to be public; all construction takes place via calls to allocator_traits<Allocator>::construct
calls. So if you provide an allocator, you could make your constructors/destructors private. Well, as long as your allocator class can access them, of course.
In short, the requirements are much less strict, but they're a bit more complex. You can get away with a lot of things if you restrict yourself from performing certain operations on the container.
Upvotes: 24