C ++中迭代器的运算符

时间:2011-05-18 18:16:06

标签: c++ macos gcc iterator compiler-errors

我正在将一个旧代码库移植到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 个答案:

答案 0 :(得分:4)

看起来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;
}

答案 1 :(得分:0)

标准运算符可以重载以支持直接比较对象,但开箱即用它们不知道要比较什么(我认为默认行为是简单地比较对象的地址,但是你的错误似乎与此相矛盾。

无论如何,How to compare two objects (the calling object and the parameter) in a class?似乎是一个非常相似的问题。

在你的课堂上,你应该添加像亚历山大建议的那样:

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

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

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

当然经过修改以满足您的比较要求。