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

Этот фрагмент кода компилирует файл в 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>' (или нет приемлемого преобразования)


person bobbyalex    schedule 09.06.2009    source источник


Ответы (4)


Тип для '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
    }
}
person Martin York    schedule 09.06.2009

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

person ralphtheninja    schedule 09.06.2009

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

person Daemin    schedule 09.06.2009
comment
Согласованный. Но что не так с этим сравнением и какова альтернатива этому типу сравнения? - person bobbyalex; 09.06.2009
comment
Это зависит от того, чего пытается достичь сравнение. Ближайшим эквивалентом является итератор, построенный по умолчанию (если итератор является указателем, то он будет NULL). - person jalf; 09.06.2009

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

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

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

IT._Has_container()

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

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

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

person Michael J    schedule 09.06.2009