Ошибка C2678 после переноса кода C ++ с VC6 на VS2008 - не найден оператор, который принимает левый операнд типа 'type'
-
13-09-2019 - |
Вопрос
Этот фрагмент кода компилирует файл в 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, это может избавить вас от проблем.