Why can't I put structures with const
values inside a container like std::vector
? (I understand the technical reason the compiler is reporting, I'm just uncertain the compiler/collection should be doing it this way)
For example, something quite simple:
struct sample {
int const a;
};
std::vector<sample> v;
v.push_back( sample{12} );
This gives an error (at least in GCC) about using the deleted operator=
. But I don't see why it should be using operator=
. It shouldn't need to use the copy operator when constructing this vector. Should it not be using the copy contructor an in-place new, which is perfectly allowed. For example, the following is okay:
sample a;
new (&a) sample{12};
Calling the destructor of sample
is also fine. That is, there are enough allowed operations on this type to construct a vector yet I am unable to do so. I thought C++11 with rvalue's and move semantics may also help here, but perhaps I'm wrong on that.
What part of the standard specifically disallow this, or is indeed a compiler error (unlikely)?
My reading of the Standard (N3290) says that your push_back
is valid.
23.2.3 para 16 (Table 101 — Optional sequence container operations) says that push_back
only requires of T
that it is MoveInsertable
.
23.2.1 para 13 defines MoveInsertable
: the following expression shall be valid:
allocator_traits<A>::construct(m, p, v);
20.6.8.2 para 5 specifies that by default (e.g., for default allocator) construct
calls placement new -- much like your expectation.
Regards, &rzej
So if you are using a conformant compiler/stdlib there will be a:
vector<T>::push_back(T&&)
overload which the temporary sample{12}
will bind to, causing it to call the move constructor of T at the reserved uninitialized storage element at v.end()
, using the temporary as a parameter. A copy constructor or assignment should not be needed to support this.
A better way would be to add a constructor to sample
and then you can call:
v.emplace_back(12)
which apart from being more succinct will also avoid the move constructor as well.
As others have stated your compiler/stdlib is not conformant, upgrade to a newer version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With