On Aug 7, 2013, at 11:20 AM, Joerg Sonnenberger <[email protected]> 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
                         pre-/post-condition               
-----------              -------------------

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 17.6.4.11 [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.

Howard


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to