Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 <vector>
#include <iostream>

struct A {
    A() {}
    A(A&) { std::cout << "A(A&) "; }
    A(const A&) { std::cout << "A(const A&) "; }
};

int main() {
    std::vector<A> 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)?

like image 823
Fedor Avatar asked Nov 18 '25 07:11

Fedor


1 Answers

I do not see any reason that the library would be required to ensure that the const overload is used.

The container copy constructor requires per [container.reqmts]/12 that the element type is CopyInsertable from a lvalue v of its type into the container regardless of the const-qualification of v. It also requires the postcondition ([container.alloc.reqmts]/2.4):

The value of v is unchanged and is equivalent to *p.

implying that if the non-const copy constructor is used, then it must not result in the value of the original object being different after the call, at least.

It is a bit less clear to me whether modification of the argument is completely forbidden, because this is stated as postscondition only. I suspect that this is the intent though.

like image 68
user17732522 Avatar answered Nov 19 '25 23:11

user17732522



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!