If one copies one std::vector
into another, or copies elements of a std::vector
in a larger (reserve
) or smaller (shrink_to_fit
) block of heap memory, what constructor of the element's type is called?
In the example program:
#include
#include
struct A {
A() {}
A(A&) { std::cout << "A(A&) "; }
A(const A&) { std::cout << "A(const A&) "; }
};
int main() {
std::vector v(1);
v.reserve(10);
auto w = v;
v.shrink_to_fit();
}
I would expect to see A(const A&) A(const A&) A(const A&)
output. But in reality the standard library implementations diverge:
libc++
prints A(const A&) A(A&) A(const A&)
,libstdc++
prints A(const A&) A(const A&) A(A&)
,A(A&) A(A&) A(A&)
.Online demo: https://gcc.godbolt.org/z/TTqxv9sd3
Is it right to assume that if the constructor from not-const
lvalue is called, then the user code is allowed modifying its argument (at least temporarily)?