Ошибка C2678 после переноса кода C ++ из VC6 в VS2008 - не найден оператор, который принимает левый операнд типа 'тип' - PullRequest
2 голосов
/ 09 июня 2009

Этот фрагмент кода компилирует файл в 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: бинарный '! =': Без оператора найдено, которое принимает левый операнд типа 'Станд :: _ Vector_iterator <_Ty, _Alloc>' (или нет приемлемого преобразования)

Ответы [ 4 ]

8 голосов
/ 09 июня 2009

Тип для '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
    }
}
2 голосов
/ 09 июня 2009

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

1 голос
/ 09 июня 2009

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

0 голосов
/ 09 июня 2009

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

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

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

IT._Has_container()

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

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

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

...