views:

275

answers:

2

I have just converted a project from Visual Studio 2003 to 2005 and although most of it 'converted' fine, I have a series of STL errors from the following line:

void SomeFn( std::vector<CSomeObject*>::iterator it,
std::vector<CSomeObject*>::iterator itBegin = NULL,
std::vector<CSomeObject*>::iterator itEnd = NULL );

The Visual Studio error is as follows:

c:\<path>\Headerfile.h(20) : error C2440: 'default argument' : cannot convert from 'int' to 'std::_Vector_iterator<_Ty,_Alloc>'
        with
        [
            _Ty=CObject *,
            _Alloc=std::allocator<CObject *>
        ]
        No constructor could take the source type, or constructor overload resolution was ambiguous

I can't see anything wrong with that code and it worked perfectly in VS 2003. Any ideas?

+2  A: 

In 2003, std::vector<T>::iterator is just T *. In 2005, at least in debug mode, it is a class, and hence you can't use NULL for its value (NULL resolves to 0).

You can use a default-constructed iterator instead:

std::vector<CSomeObject*>::iterator itBegin = std::vector<CSomeObject*>::iterator()
Sunlight
+10  A: 

Your program is incorrect as NULL cannot be converted as an iterator. I don't really know what you want these iterators to be initialized as. If you need an iterator guarantied not to be in a container but to be still "valid", you can use a default-constructor:

typedef std::vector<CSomeObject*> myvector_t;
void SomeFn( myvector_t::iterator it,
             myvector_t::iterator itBegin = myvector_t::iterator(),
             myvector_t::iterator itEnd = myvector_t::iterator() );

Note, however, that if you do so, it, itBegin and itEnd won't be comparable in a meaningful way! Only iterators obtained from a given container are comparable meaningfully. In the end, I would recommend against using defaults values for itBegin and itEnd. If you really need to not have these, create another function without the arguments and do something meaningful. i.e.:

typedef std::vector<CSomeObject*> myvector_t;
void SomeFn( myvector_t::iterator it,
             myvector_t::iterator itBegin,
             myvector_t::iterator itEnd );
void SomeFn( myvector_t::iterator it ); // No begin/end arguments

Another problem of your program is the use of a vector to store pointers. This is really unsafe. Make sure you never erase elements from the vector without deleting the element first. You might also have problems with algorithms copying objects around. It is better to use smart pointers in vectors.

PierreBdR