ошибка C2664 - код прекрасно компилируется в VC6; не в VS 2010 - PullRequest
0 голосов
/ 23 июля 2010

У меня есть typedef, класс с вектором-членом, использующим этот тип, а затем метод, использующий std :: :: 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;
}

Подробная ошибка:
ошибка C2664: 'std :: _ Vector_iterator <_Myvec> std :: vector <_Ty> :: erase (std :: _ Vector_const_iterator <_Myvec>, std :: _ Vector_const_iterator <_Myvec>)': невозможно преобразовать параметр 1 из «const WordNo_t» в 'станд :: _ Vector_const_iterator <_Myvec>'

Довольно новый для STL ... Любая помощь будет оценена.

Ответы [ 2 ]

2 голосов
/ 23 июля 2010

Я удивлен, begin и end даже компилируются, они не должны. std::vector (и друзья) используют итераторы, а не указатели. (Хотя они должны действовать аналогично.)

В любом случае, erase принимает итератор, а не указатель. Поскольку векторы являются смежными, вы можете создавать служебные функции как таковые:

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]);
}

По сути, выясните, сколько элементов pPtr из &pVec[0] (первый элемент), затем добавьте это к pVec.begin(). (Преобразуйте смещение от указателя и указателя для начала в смещение от начала.) Эта операция O (1). А потом:

void truncate (WordNo_t *Ptr)
{
    // note the == end() bit will be in here anyway:
    m_Words.erase(to_iterator(Ptr, m_Words), end());
}
2 голосов
/ 23 июля 2010

Указатель не является итератором.erase принимает итератор, но вы передаете ему указатель.Возможно, вам следует изменить truncate, чтобы также использовать итератор?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...