More n3644 changes - forward_list and deque

Howard Hinnant hhinnant at
Wed Aug 7 09:51:09 PDT 2013

On Aug 7, 2013, at 11:20 AM, Joerg Sonnenberger <joerg at> wrote:

> On Tue, Aug 06, 2013 at 03:18:42PM -0400, Howard Hinnant wrote:
>> Do you think debug mode would be more helpful, or less helpful, if the
>> relational operators trapped a less-than comparison between two
>> iterators i and j where i and j belong to two different vectors?
> Does it ever make sense to put iterators into a std::map? I think it
> does, so allowing relation operators would be sensible.

I'm going to slightly reword your question so that it more accurately targets our discussion.  Please let me know if I've mangled your intended question.  My intent is to clarify your words for us all, and not to mangle what you were trying to say.

Does it ever make sense to put random access iterators referring to more than one container into a single std::map?

In using a std::map in this way, one would likely have to also store in the map which container each iterator referred to, else the iterator would be only as useful as a pointer or reference.  E.g. else you could not decrement the iterator, or use it to insert or erase.  You could dereference it, and you could increment it exactly once.  You could also equality-compare it to other iterators of like kind.  One would also of course have to carefully manage iterator invalidation.  This all sounds possible to me, though a little dubious (I might well reject it in a code review).  And the order imposed by the std::map would be unpredictable and meaningless.

Ultimately however I believe such a design still runs afoul of the standard.  Table 111 - Random access iterator requirements has:

Expression:               Assertion / note
-----------              -------------------

a < b                    < is a total ordering relation

I'm reading this as a pre-condition, a violation of which is generically classified to be undefined behavior by [res.on.requried]/p1:

Violation of the preconditions specified in a function’s Requires: paragraph results in undefined behavior unless the function’s Throws: paragraph specifies throwing an exception when the precondition is violated.

I'm also interpreting the expression as not a total ordering relation when a and b refer to different containers.  Perhaps I'm wrong on that point, not sure yet.

If the example was highly motivating, it might be worth it to bend the rules here.  But I'm not finding the example highly motivating.  The example seems like fragile, unwieldy and unlikely code.

I know at one time both the gcc and Metrowerks debug mode trapped less-than comparisons of iterators into different containers.  I do not know if they still do.  I don't recall seeing any complaints about this behavior.  I've searched SO and the net in general, and can't find any use cases of less-than comparisons of iterators into different containers, nor any complaints about debug-mode iterators trapping the behavior.

I would take this question to the LWG (and almost did), except that I can't find any standards question to ask.

Ultimately we need to do what is in the best interest of libc++ customers.  If that means trying to get the standard changed, then ok.  If that means bending rules from the standard in debug mode, ok.  I currently believe that trapping less-than comparisons among iterators pointing into different containers in debug mode is in the best interest of libc++ customers.


More information about the cfe-commits mailing list