[PATCH] 77864 Fix noexcept conditions for map/set default constructors

Tim Song t.canens.cpp@gmail.com
Wed Oct 12 21:26:00 GMT 2016


On Wed, Oct 12, 2016 at 4:36 PM, François Dumont <frs.dumont@gmail.com> wrote:
> On 10/10/2016 23:01, Tim Song wrote:
>>
>> Trying again...with a few edits.
>>
>>> On Mon, Oct 10, 2016 at 3:24 PM, François Dumont <frs.dumont@gmail.com>
>>> wrote:
>>>
>>> @@ -602,24 +612,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>>           struct _Rb_tree_impl : public _Node_allocator
>>>           {
>>>     _Key_compare _M_key_compare;
>>> -  _Rb_tree_node_base _M_header;
>>> +  _Rb_header_node _M_header;
>>> +#if __cplusplus < 201103L
>>>     size_type _M_node_count; // Keeps track of size of tree.
>>> +#else
>>> +  size_type _M_node_count = 0; // Keeps track of size of tree.
>>> +#endif
>>>
>>> +#if __cplusplus < 201103L
>>>     _Rb_tree_impl()
>>> -  : _Node_allocator(), _M_key_compare(), _M_header(),
>>> -    _M_node_count(0)
>>> -  { _M_initialize(); }
>>> +  : _M_node_count(0)
>>> +  { }
>>> +#else
>>> +  _Rb_tree_impl() = default;
>>> +#endif
>>
>>
>> The default constructor of the associative containers is required to
>> value-initialize the comparator (see their synopses in
>> [map/set/multimap/multiset.overview]).
>
> I don't have latest Standard version so can't see the exact word but I find
> quite annoying that the Standard doesn't allow this simple implementation.

The "exact word" is:

    map() : map(Compare()) { }

which mandates the comparator be copied from a value-initialized Compare.
The use of () means value-initialization.

>
> I don't know if unodered containers have same kind of requirements for equal
> or hash functors but if so current implementation doesn't do this value
> initialization.


Yes, unordered_meows are required to do that as well. See, e.g.,
https://timsong-cpp.github.io/cppwp/unord.map.cnstr:

unordered_map() : unordered_map(size_type(see below)) { }
explicit unordered_map(size_type n,
                                      const hasher& hf = hasher(),
                                      const key_equal& eql = key_equal(),
                                      const allocator_type& a =
allocator_type());

The default constructor is specified to call the second constructor,
which copies the hasher etc. from a value-initialized object.

Tim

>
> So here is another attempt. This time it simply allows to have noexcept
> condition in one place and closer to where operations are being invoked.
>
> Ok to commit after tests ?
>
> François
>
>>
>>   _Rb_tree_impl() = default; doesn't do that; it default-initializes the
>>   comparator instead.
>>
>> Tim
>>
>



More information about the Gcc-patches mailing list