C++ 中迭代器的运算符

发布于 2024-11-08 07:05:42 字数 4856 浏览 0 评论 0原文

我正在将旧代码库移植到 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;
}

出现如下错误:错误:ISO C++ 说这些是不明确的,即使第一个的最差转换比第二个的最差转换要好:

什么是我缺少核心概念吗?

更新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 - [email protected]
    // { 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;
};

I am porting an old code base to OSX.

I have the following snippet of code:

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()) {

I get an error that says: error: no match for 'operator!=' in 'lastVisible != 0'

I dont follow, I thought operations like != and ==, etc were standard operations. Why the complaint from the compiler?

UPDATE: I am trying to understand the comparison of objects. What if the code is like this:

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

with errors like: 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:

What is the core concept I am missing?

Update 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 - [email protected]
    // { 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;
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

等往事风中吹 2024-11-15 07:05:42

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

It looks that lastVisible is an object rather than just a pointer. If you compare some object with something, then it has to have the appropriate operator.

Maybe this would compile?

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())
{ ...

Or if FxLayerList is just a collection of pointers to FxLayer, this would be more straightforward:

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())
{ ...

Answer to UPDATE: see my comment below. The problem (compiler error message) can be solved by explicitly retrieving the pointer from the "smart" pointer:

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;
}
甜柠檬 2024-11-15 07:05:42

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

无论如何,如何比较类中的两个对象(调用对象和参数)?似乎是一个非常相似的问题。

在你的班级中,你可能应该添加类似亚历山大上面建议的内容:

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

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

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

当然要修改以满足你的比较要求。

The standard operators are overloadable to support directly comparing objects, but out of the box they wouldn't know what to compare (I think the default behaviour would be to simply compare the object's address, but your error seems to contradict that).

In any event, How to compare two objects (the calling object and the parameter) in a class? seems to be a very similar problem.

Within your class you should probably add in something like what Alexander suggested above:

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

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

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

Of course modified to suit your comparison requirements.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文