I’m still confused about the behaviour of std::vector::resize(). Consider the following code (see also type requirements for std::vector<type>)
struct A {
A() : X(0) { std::cerr<<" A::A(); this="<<this<<'\n'; }
A(A const&) { assert(0); } // is required but doesn't fire in vector::resize
int X;
};
int main()
{
std::vector<A> a;
a.resize(4); // would not compile without A::A(A const&) or A::A(A&&)
}
Without A::A(A const&) or A::A(A&&), the line with a.resize(4); doesn’t compile. However, that constructor is never called: the assert(0) doesn’t fire! Can somebody explain that to me?
My interpretation is that the presence of either of these constructors is required by the template magic of allocator_traits<> (used by std::vector::resize()), but is actually never called. However, why would you require the presence of a method if you’re not calling it?
The latest revision of the standard (n3376) says:
The implication is that
MoveInsertableis required for any reallocation that might occur, whileDefaultInsertableis required for the actual appending. So your copy or move constructor will fire only if your vector already contains elements and needs to be reallocated.Indeed, if we write:
then the copy- or move-constructor of
Ais called, and your assert is triggered.