map<const T, const U> is assignable even though pair<const T, const U> is not

Daniel Krügler daniel.kruegler@gmail.com
Thu Apr 23 13:07:00 GMT 2015


2015-04-23 14:39 GMT+02:00 Jonathan Wakely <jwakely@redhat.com>:
> On 23/04/15 11:48 +0100, Jonathan Wakely wrote:
>>
>> Marshall Clow sent me this problem:
>>
>> On 22 April 2015 at 21:49, Marshall Clow wrote:
>>>
>>> The following code fails to compile w/libc++, but succeeds with
>>> libstdc++.
>>>
>>> #include <map>
>>>
>>> int main () {
>>> std::map<const int, const int> foo1, foo2;
>>> foo2 = foo1;
>>> }
>>>
>>> assigning a allocator-aware container requires that the value type
>>> be
>>> CopyAssignable, which pair<const int, const int> is definitely not.
>>>
>>
>> I think this is a consequence of our optimization to recycle nodes on
>> assignment, which runs a destructor and then constructs a new element
>> with placement new, so it doesn't actually do any assignments.
>>
>> The example violates the preconditions on the assignment, so it's
>> undefined behaviour, but it's a bit surprising that it Just Works.
>>
>> Do we want to make this type non-CopyAssignable?
>
> Answering myself ... I don't think we should change anything, given
> that pair<const T, U> is already not assignable, and we have to make
> map<T, U> assignable despite that.

To me these comparisons don't hold: I don't find it surprising that

map<T, U>

works for non-const T *albeit* semantically the values are pair<const
T, U> values, because for these container the key is actually never
needed to be *replaced*. Either in a unique-key container there is
only one of it or in a non-unique-key container each duplicate is
added (but does not replace the older one). But from the user
perspective the *mapped values* should be sensitive to
const-correctness.

Therefore I would appreciate making

std::map<T, const U>

non-CopyAssignable.

- Daniel



More information about the Libstdc++ mailing list