views:

660

answers:

4

This piece of code compiles file in VC6 but in VS 2008 it gives an error. Can anyone tell me why? I guess it is because you can no longer compare a pointer to NULL (which is a typedef for 0). If that is the case, how do I do this comparison in VC9?

for ( std::vector<aCattrBase*>::iterator iT = attrLst.begin(); iT < attrLst.end(); iT++)
     { 
      if ( (iT != NULL) && (*iT != NULL) ) //Error: C2678
      {
//code
}
}

error C2678: binary '!=' : no operator found which takes a left-hand operand of type 'std::_Vector_iterator<_Ty,_Alloc>' (or there is no acceptable conversion)

+1  A: 

You're trying to compare the iterator to NULL in the first condition in the if statement. You do not need this first comparison as the iterator iT should alays be within the valid portion of the list.

Daemin
Agreed. But what is wrong with the comparison and what is the alternative for this type of comparison?
Bobby Alexander
That depends on what the comparison is trying to achieve. The closest equivalent is a default-constructed iterator (if the iterator is a pointer, then that will be NULL).
jalf
+7  A: 

The type for 'std::vector::iterator' is not necessarily a pointer type so you can not compare it to NULL.

In your old compiler it just happened to be a pointer and so your code compiled. But you just got lucky (as shown when you moved the code to a different compiler).

The only test on iterator you have is to compare it to end() or begin() or any valid iterator within the range begin() -> end(). Since this is a vector you can do mathematical operations with the iterator. iT-begin() should give you an offset. But this is not valid for all containers (check each containers documentation).

All you need to do is test what the iterator points at:

for ( std::vector<aCattrBase*>::iterator iT = attrLst.begin();
      iT != attrLst.end();  // Changed this. Notice the !=
      ++iT)                 // Changed this. Prefer pre increment for not integer types
{ 
    if ( *iT != NULL)
    {
         //code
    }
}
Martin York
+2  A: 

The iterator is not a pointer, it's a class instance and does not have the binary operator != to compare it with null.

Magnus Skog
A: 

Comparing an iterator to NULL was never legal. VC6 let you do it, but was wrong to do so.

In the example you give, the comparison is meaningless, as the iterator will always point to something. Checking (*IT)!=NULL is reasonable and still works.

If there is a real prospect that an iterator does not point to a valid object, VC9 has an undocumented function

IT._Has_container()

that will be true if an iterator points to a container and false if the iterator does not. To set the iterator to nothing, you assign an empty iterator:

IT = std::vector<aCattrBase*>::iterator();

The above represents non-portable code and fairly poor style and I don't recommend designing anything to use it. However if you need to quickly get some VC6 code to compile on VC9, it might get you out of trouble.

Michael J