Reputation: 1
I've updated to a newer C++ compiler (going from Visual C++ 6.0 to Visual C++ 2015) and I am working on converting a Vector template class to be compatible. One error I am encountering involves the vector::erase method and the input type.
Template class snippet:
template<class Type> class Vector {
public:
typedef Type* iterator;
typedef const Type* const_iterator;
...
iterator erase( const_iterator iBegin );
iterator erase( const_iterator iBegin, iEnd );
private:
VectorImpl<Type>* m_pImpl;
};
...
template <typename Type> typename Vector<Type>::iterator Vector<Type>::erase(
typename Vector<Type>::const_iterator iBegin )
{
return m_pImpl->erase( iBegin );
};
...
Error:
C2440: 'initializing': cannot convert from 'const int*' to 'std::_Vector_const_iterator>>'
I was able to convert a std::vector iterator to an int* by dereferencing the iterator but I'm not sure how to do the inverse:
template <typename Type> typename Vector<Type>::const_iterator Vector<Type>::begin()
{
Vector<Type>::const_iterator begin = &(*m_pImpl->begin());
return begin;
};
Q: Is it possible to convert a const int* to a std::vector const_iterator?
Upvotes: 0
Views: 2257
Reputation: 385108
I was able to convert a std::vector iterator to an int* by dereferencing the iterator but I'm not sure how to do the inverse
You should bear in mind that pointers and iterators are not the same thing. Pointers are a kind of iterator, but the reverse is not true.
You can get the address of some element, by taking an iterator to that element, dereferencing the iterator, then taking the address of the result.
But it is not particularly meaningful to transform a raw pointer into an iterator. In general this would be like pouring some orange juice into water then trying to separate the two afterwards. It is advisable to stick with iterators across the board.
However, see below.
Is it possible to convert a const int* to a std::vector const_iterator?
Actually, yes. If you know that the pointer is valid, and you are definitely only using vectors, you can rely on vector data contiguity:
const int* ptr = ...;
const int* first = &vec[0];
const size_t dist = ptr - first;
auto it = vec.cbegin() + dist;
Now it
is what you want.
But this is hackery relying on pointer and iterator arithmetic, the former of which will only work on a vector, and the latter of which will only be efficient on a sequence container (and requires std::advance
instead on other containers, as a result).
I would not accept this in production code without a very good reason steered by limitations of a third-party library.
It seems to me that you should replace Vector
with std::vector
across the board. I understand that this may be problematic if you cannot (or do not want to) change the code's outward-facing interface. In that case, frankly, I'd leave std::vector
out of it because these are two separate implementations that are going to rub up against one another.
Upvotes: 2