Reputation: 841
In c++ primer, pg 95 the author says that c++ programmers tend to use != in preference of < when writing loops.
for (vector<int>::size_type i = 0; i != 10; ++i) is preferred instead of
for (vector<int>::size_type i = 0; i < 10; ++i)
I read the same thing in accelerated c++. Can someone explain the rationale behind this
Upvotes: 26
Views: 2261
Reputation: 17637
Maybe those who preffer this is because they got used to checking for null, etc... so preffer use the same != in everything.
if(x != null) { ... }
for(int i=0; i != 10; i++) { ... }
so for those everyting tends to be != or ==
read != as DIFFERENT/NOT EQUAL, following the same principle as == is EQUAL,
Upvotes: 0
Reputation: 15997
It's a habit for generic programming; for example, you can easiely use <
with indices, but you cannot use that with all iterator types. A list iterator cannot efficiently implement <
- however, !=
can be implemented for even the simplest of iterator types. Therefore, it is a good habit to always use the most generic comparison - it makes your code more resilient to change.
Upvotes: 31
Reputation: 320391
The requirement of being "relationally comparable" is a much stronger one than the requirement of being "equally comparable". When it comes to iterating over containers, the possibility to perform relational comparison between iterators or generic indices (like <
, >
, <=
etc.) is strongly associated with random-access containers, while the equality comparisons are more universally applicable (and often the only ones available when working with sequential access containers).
In general, it is a good practice to make you code as generic as possible, i.e. you should never rely on stronger requirements when weaker requirements are perfectly sufficient. In other words, if you can implement your algorithm by using equality comparisons only, it is better to do it that way, without bringing in any relational comparisons. It is possible that way you will make your algorithm more usable with a wider range of underlying data structures (containers).
Of course if you don't care about this kind of genericity or simply don't need it, you can just ignore these considerations and use either approach.
Upvotes: 7
Reputation: 47592
Think of the case when one have to increment by lets say 3 instead of 1.
for (vector<int>::size_type i = 0; i != 10; i+=3)
This will run forever since it will skip 10 and go to 12 instead and increment forever.
for (vector<int>::size_type i = 0; i < 10; i+=3)
This will work fine in this case too. So != is not always a good choice.
Upvotes: 11
Reputation: 361342
If you write !=
, then you can reverse the loop iteration with minimal change.
Suppose you first write:
for ( int i = m; i != n ; i++ )
Later you reverse it:
for ( int i = n ; i != m ; i-- )
Not so appealing, but still it requires less analysis than "<" and ">".
Upvotes: 7
Reputation: 992887
When using some kinds of STL iterators (those that aren't random access), you must use !=
:
for (map<int,int>::iterator i = a.begin(); i != a.end(); ++i) ...
However, I don't see any reason to prefer !=
for well-ordered scalar types as in your example. I would usually prefer <
for scalar types and !=
for all iterator types.
Upvotes: 44
Reputation: 23789
Because, in general, not all iterators support the "<" operation. See the manual for operation supported by each iterator type. Only random access iterators (of which, simple pointers are a subset) support inequality comparisons (< and >) between iterators
Upvotes: 8