https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #5 from frankhb1989 at gmail dot com ---
(In reply to Jonathan Wakely from comment #4)
> This might strictly conform to the requirements, but it's stupid. Why would
> you do that?
> 
> Allocator equality doesn't care about the value type, as evidenced by the
> requirement that a==b is equivalent to a==Y::rebind<T>::other(b). So if the
> result of == doesn't care about the value type, then why would
> is_always_equal depend on it?

Because I find no standard rules to prevent such stupid things. With such
cases, the container implementations are potentially broken: if the node
allocator is not is_always_true nor POCCA, and it actually throws on
comparison, then the noexcept specification will cause the program terminate.
This is quite counterintuitive, and I don't see this is intended anyway.

Probably the easiest resolution is to add one more requirement of invariant on
is_always_equal in the standard to ensure that each rebind result will keep
is_always_equal unchanged. This is likely to be a DR as is_always_equal has
been explicitly used as the part of noexcept specifications of containers'
operator= in the standard, and I don't see the way to fix it merely for
individual node-based container implementations. (Not sure traits like POCCA
need the additional requirement, though.)

And the noexcept exceptions provided in the current implementations are really
inconsistent, for instance, between move operator= of std::list and std::map.
Whether the fix above is adopted, at least one container implementation in
libstdc++ is not conforming.

Allocator-extended move constructors are similarly broken despite the explicit
noexcept specifications required in the standard. However, if it is resolved by
the fix in the standard, the implementation can remain unchanged.

Reply via email to