Ошибка C2678 после переноса кода C ++ с VC6 на VS2008 - не найден оператор, который принимает левый операнд типа 'type'

StackOverflow https://stackoverflow.com/questions/968602

Вопрос

Этот фрагмент кода компилирует файл в VC6, но в VS 2008 он выдает ошибку.Кто-нибудь может сказать мне, почему?Я предполагаю, это потому, что вы больше не можете сравнивать указатель с NULL (который является typedef для 0).Если это так, то как мне провести это сравнение в VC9?

for ( std::vector<aCattrBase*>::iterator iT = attrLst.begin(); iT < attrLst.end(); iT++)
        { 
            if ( (iT != NULL) && (*iT != NULL) ) //Error: C2678
            {
//code
}
}

ошибка C2678:двоичный файл '!=' :не найден оператор , который принимает левый операнд типа 'std::_Vector_iterator<_Ty,_Alloc>' (или нет приемлемого преобразования)

Это было полезно?

Решение

Тип для 'std::vector ::iterator' не обязательно является типом указателя, поэтому вы не можете сравнить его с NULL.

В вашем старом компиляторе это просто был указатель, и поэтому ваш код скомпилировался.Но вам просто повезло (как показано, когда вы перенесли код на другой компилятор).

Единственный тест на итераторе, который у вас есть, - это сравнить его с end() или begin() или любым допустимым итератором в диапазоне begin() -> end().Поскольку это вектор, вы можете выполнять математические операции с итератором.iT-begin() должен дать вам смещение.Но это справедливо не для всех контейнеров (проверьте документацию по каждому контейнеру).

Все, что вам нужно сделать, это проверить, на что указывает итератор:

for ( std::vector<aCattrBase*>::iterator iT = attrLst.begin();
      iT != attrLst.end();  // Changed this. Notice the !=
      ++iT)                 // Changed this. Prefer pre increment for not integer types
{ 
    if ( *iT != NULL)
    {
         //code
    }
}

Другие советы

Итератор не является указателем, это экземпляр класса и не имеет двоичного оператора !=, чтобы сравнить его с null.

Вы пытаетесь сравнить итератор с NULL в первом условии оператора if.Вам не нужно это первое сравнение, так как итератор всегда должен находиться в пределах допустимой части списка.

Сравнение итератора с NULL никогда не было законным.VC6 позволил вам сделать это, но поступил неправильно.

В приведенном вами примере сравнение бессмысленно, так как итератор всегда будет указывать на что-то.Проверка (* IT)!=NULL является разумной и все еще работает.

Если существует реальная вероятность того, что итератор не укажет на допустимый объект, VC9 имеет недокументированную функцию

IT._Has_container()

это будет true, если итератор указывает на контейнер, и false, если итератор этого не делает.Чтобы установить для итератора значение nothing, вы назначаете пустой итератор:

IT = std::vector<aCattrBase*>::iterator();

Приведенное выше представляет собой непереносимый код и довольно плохой стиль, и я не рекомендую разрабатывать что-либо для его использования.Однако, если вам нужно быстро получить некоторый код VC6 для компиляции на VC9, это может избавить вас от проблем.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top