c++vectorallocationmove-constructormove-assignment-operator

Can I reliably emplace_back in a vector of a type that does not have an assignment operator?


I made some tests in GCC, Clang and MSVC and found out that emplace_back never calls an assignment operator on the contained class. It only calls the copy or move constructor when reallocation takes place. Is this behavior somehow guaranteed by the standard?

The use case is that I have some classes to be sequentially stored in a number that only grows along time until the whole vector is destructed. I'd be happy to clean my code from the assignment operators.


Solution

  • These requirements are documented at cppreference.com.

    For std::vector<T>::emplace_back :

    Type requirements

    -T (the container's element type) must meet the requirements of MoveInsertable and EmplaceConstructible.

    Additionally std::vector has a general requirement that the type has to be Erasable.

    EmplaceConstructible requires that the type is constructible using the given allocator, with the arguments provided. Since you are using the default allocator std::allocator<T>, this just means that the type has an accessible constructor with those arguments.

    MoveInsertable requires that the type is constructible using the given allocator, using an rvalue of type T. For std::allocator this means that the type has an accessible move constructor.

    Erasable requires that the type is destructible using the given allocator. For std::allocator this means that is has an accessible destructor.

    That's it (except for some rules about complete vs. incomplete types). There are no requirements that mention assignment operators.

    But until C++11, it used to be that the type always had to be be CopyAssignable and CopyConstructible. This has since been relaxed. Now, except for Erasable, the requirements just depend on the operations performed on the vector.