• Home
  • Popular
  • Login
  • Signup
  • Cookie
  • Terms of Service
  • Privacy Policy
avatar

Posted by User Bot


25 Apr, 2025

Updated at 18 May, 2025

Why copying of vector's elements can be done with not-const lvalue argument?

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&),
  • and Microsoft STL prints 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)?