tags:

views:

81

answers:

2

I have a typedef, a class with a member vector using that type and then a method using std::<vector>::erase().

#typedef DWORD WordNo_t;

class CWordList : public CObject
{
public:
WordNo_t* begin() { return m_Words.begin(); }
WordNo_t* end()   { return m_Words.end(); }
void truncate (WordNo_t *Ptr)
{
  if (Ptr == end())
    return;
  ASSERT (Ptr >= begin() && Ptr < end());
  // following line generates C2664
  m_Words.erase (Ptr, end());
}

private:
  std:vector<WordNo_t> m_Words;
}

The detailed error is:
error C2664: 'std::_Vector_iterator<_Myvec> std::vector<_Ty>::erase(std::_Vector_const_iterator<_Myvec>,std::_Vector_const_iterator<_Myvec>)' : cannot convert parameter 1 from 'const WordNo_t' to 'std::_Vector_const_iterator<_Myvec>'

Pretty new to STL... Any help would be appreciated.

+2  A: 

A pointer is not an iterator. erase takes an iterator but you are passing it a pointer. Perhaps you should change truncate to also take an iterator?

Charles Bailey
+1  A: 

I'm surprised begin and end are even compiling, they shouldn't. std::vector (and friends) use iterators, not pointers. (Though they are intended to act similarly.)

In any case, erase takes an iterator, not a pointer. Because vectors are contiguous, you can make utility functions as such, though:

template <typename T, typename A>
typename std::vector<T, A>::iterator
to_iterator(T* pPtr, std::vector<T, A>& pVec)
{
    ASSERT(pPtr >= &pVec.front() && pPtr <= &pVec.back());

    return pVec.begin() + (pPtr- &pVec[0]);
}

template <typename T, typename A>
typename std::vector<T, A>::const_iterator
to_iterator(const T* pPtr, const std::vector<T, A>& pVec)
{
    ASSERT(pPtr >= &pVec.front() && pPtr <= &pVec.back());

    return pVec.begin() + (pPtr - &pVec[0]);
}

Basically, find out how many elements pPtr is from &pVec[0] (the first element), then add that to pVec.begin(). (Transform the offset from a pointer and the pointer to start into the offset from the start.) This operation is O(1). And then:

void truncate (WordNo_t *Ptr)
{
    // note the == end() bit will be in here anyway:
    m_Words.erase(to_iterator(Ptr, m_Words), end());
}
GMan
Thank you! begin() and end() actually were not compiling as above, but I found an answer for that part. I just thought I'd post the original code that compiled in VC6, and highlight the specific part I was having trouble with now. Thanks again!
@paorear: No problem, let me know if something doesn't make sense.
GMan