0

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?

4
  • No, they are distinct types in general. In fact, to create a const_iterator that points to something you'll need another iterator, or the container itself. Commented Sep 11, 2018 at 15:07
  • I haven't tried to compile this code, but it clearly has more errors than that. Those ...'s are clearly suspect. Post the smallest code sample that you can create that shows the problem. For example, although your question mentions std::vector const_iterator, there is nothing in this code that mentions std::vector or its iterators. Commented Sep 11, 2018 at 15:11
  • Where is the std::vector? Commented Sep 11, 2018 at 15:14
  • Is there any reason you appear to be using PIMPL? Commented Mar 4, 2020 at 21:49

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.