операторы на итераторах в C ++ - PullRequest
0 голосов
/ 18 мая 2011

Я портирую старую кодовую базу на OSX.

У меня есть следующий фрагмент кода:

FxLayerList::iterator lastVisible = NULL;
for (FxLayerList::iterator iter = mBranch.begin(); iter != mBranch.end(); iter++) {
    if ( (*iter)->IsVisible() && !(*iter)->IsBypass()) {
        lastVisible = iter;
    }
}
if (lastVisible != NULL && (*lastVisible)->GetGeneratedImage()) {

Я получаю сообщение об ошибке: error: no match for 'operator!=' in 'lastVisible != 0'

Я не следую, я думал, что такие операции, как! = И ==, и т. Д. Были стандартными операциями Почему жалоба от компилятора?

ОБНОВЛЕНИЕ: я пытаюсь понять сравнение объектов. Что, если код такой:

FxBool FxLayerList::Contains(FxLayer *layer) const
{
for (FxLayerList::const_iterator iter=this->begin(); iter != this->end(); iter++)
{
    if ((*iter) == layer) {
        return true;
    }   
}
return false;
}

с ошибками типа: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:

Какая основная концепция мне не хватает?

Обновление 2:

// FxSmartPtr is a smart pointer that is also typed for each class, avoiding the need for any casting.
// Setting an FxSmartPtr to NULL actually kills the memory that it's pointing to as well.
template <class eachClass>
class FxSmartPtr
{
public:
// Construction

// Default constructor makes an empty container.
FxSmartPtr(void) : mPtr(NULL) {}

// Construction with a ptr adds one reference to it.
FxSmartPtr(eachClass *ptr) : mPtr(ptr) { this->Reference(); }

// Copy construction means that both smart pointers end up with a reference to the object.
FxSmartPtr(const FxSmartPtr & inPtr) :mPtr(NULL) { FrAssignRef(mPtr,(eachClass *)inPtr.mPtr); }

// Default construction
FxSmartPtr(FxConstructArg cons) { if (cons == FcNew) mPtr = new eachClass(); }
FxSmartPtr(FxConstructArg cons,eachClass *ptr) { if (cons == FcNew) mPtr = ptr; }

// Destructor removes only the one reference that we own.
~FxSmartPtr() { this->Dispose(); }


// Most important and common use is via assignment. References are always safely balanced.

// AssignReference safely replaces one reference counted ptr with another. 
static inline eachClass * FrAssignRef(eachClass *& to, eachClass * from)
    { if (from) from->AddReference(); if (to) to->RemoveReference(); to = from; return to; }

// If you assign a pointer to this object we add one reference count to it.
const FxSmartPtr<eachClass> & operator = (const eachClass *ptr)
    { FrAssignRef(mPtr,(eachClass *)ptr); return *this; }

// Replace our referenced object with a reference added to the incoming one.
const FxSmartPtr<eachClass> & operator = (const FxSmartPtr & inPtr)
    { FrAssignRef(mPtr,(eachClass *)inPtr.mPtr); return *this; }

// Assignment to a dumb pointer takes/gives no references.
operator eachClass * (void) const
    { return mPtr; }
eachClass * operator->(void)
    { if (mPtr != NULL) if (mPtr->GetRefCount() < 1 || mPtr->GetRefCount() > 10000) ASSERT(0); return mPtr; }
const eachClass * operator->(void) const
    { if (mPtr != NULL) if (mPtr->GetRefCount() < 1 || mPtr->GetRefCount() > 10000) ASSERT(0); return mPtr; }


// Explicit assignment and object transfers

// Get() - return ptr with no reference
eachClass * Get(void) const
    { return mPtr; }
eachClass * GetPtr(void)
    { return mPtr; }

// Own() - return ownership with ptr
eachClass * Own(void)
    { if (mPtr) mPtr->AddReference(); return mPtr; }

// Set() - we take our own reference on your object
FxSmartPtr<eachClass> & Set(eachClass * ptr)
    { FrAssignRef(mPtr, ptr); return *this; }

// Take() - you give us your reference
FxSmartPtr<eachClass> & Take(eachClass * ptr)
    { FrDispose(mPtr); mPtr = ptr; return *this; }


// Comparison operators compare the pointers contained in each
FxBool operator == (const FxSmartPtr & inPtr) const
    { return (mPtr == inPtr.mPtr); }
FxBool operator == (const eachClass * inPtr) const
    { return (mPtr == inPtr); }
FxBool operator != (const FxSmartPtr & inPtr) const
    { return (mPtr != inPtr.mPtr); }
FxBool operator != (const eachClass * inPtr) const
    { return (mPtr != inPtr); }

// Reference() and Dispose() change the normal reference count. If you use these then
// you end up having to count references externally.

// Safely take a reference if the ptr is not nil
void Reference(void) { if (mPtr != NULL) mPtr->AddReference(); }
// Safely dispose one reference count.
void Dispose(void) { if (mPtr != NULL)
    // JASON/INDIE - SLACKMOEHRLE@GMAIL.COM
    // { ULONG refs = mPtr->GetRefCount(); mPtr->RemoveReference(); if (refs <= 1) mPtr = NULL; } }
    { FxUInt32 refs = mPtr->GetRefCount(); mPtr->RemoveReference(); if (refs <= 1) mPtr = NULL; } }

protected:

    eachClass *mPtr;
};

Ответы [ 2 ]

4 голосов
/ 18 мая 2011

Похоже, что lastVisible является объектом, а не просто указателем.Если вы сравниваете некоторый объект с чем-то, то он должен иметь соответствующий оператор.

Может быть, это скомпилируется?

FxLayerList::iterator lastVisible = mBranch.end();
for (FxLayerList::iterator iter = mBranch.begin(); iter != mBranch.end(); iter++)
{
    if ( (*iter)->IsVisible() && !(*iter)->IsBypass())
    {
       lastVisible = iter;
    }
}
if (lastVisible != mBranch.end() && (*lastVisible)->GetGeneratedImage())
{ ...

Или, если FxLayerList - это просто набор указателей на FxLayer, это было бы более просто:

FxLayer *lastVisible = NULL;
for (FxLayerList::iterator iter = mBranch.begin(); iter != mBranch.end(); iter++)
{
    if ( (*iter)->IsVisible() && !(*iter)->IsBypass())
    {
        lastVisible = *iter;
    }
}
if (lastVisible != NULL && lastVisible->GetGeneratedImage())
{ ...

Ответ на ОБНОВЛЕНИЕ : см. Мой комментарий ниже.Проблема (сообщение об ошибке компилятора) может быть решена путем явного извлечения указателя из «умного» указателя:

FxBool FxLayerList::Contains(FxLayer *layer) const
{
    for (FxLayerList::const_iterator iter=this->begin(); iter != this->end(); iter++)
    {
        if (iter.Get() == layer) {
            return true;
        }   
    }
    return false;
}
0 голосов
/ 18 мая 2011

Стандартные операторы перегружаются для поддержки непосредственного сравнения объектов, но из коробки они не будут знать, что сравнивать (я думаю поведение по умолчанию будет просто сравнивать адрес объекта, но вашошибка, кажется, противоречит этому).

В любом случае, Как сравнить два объекта (вызывающий объект и параметр) в классе? представляется очень похожей проблемой.

В вашем классе вы, вероятно, должны добавить что-то вроде того, что Александр предложил выше:

int Date :: Compare (const Date& d) {

  if (year<d.year) {
    return -1;
  }
}

bool operator == (const Date& d) const {
   return !Compare(d);
}

Конечно, модифицировано для соответствия вашим требованиям сравнения.

...