开发者

Problem C++ STD Iterator comparison operators

开发者 https://www.devze.com 2023-01-26 13:01 出处:网络
Good day sirs, because it looks like mine isn\'t going to be that good. I have a class C, which doesn\'t have any children but has a vector made of pointers to instances of another class, let\'s cal

Good day sirs,

because it looks like mine isn't going to be that good.

I have a class C, which doesn't have any children but has a vector made of pointers to instances of another class, let's call it B:

class C
{
    public:
       ...
       std::vector<B*> elements;
       ...
}

B also has a vector of pointers to instances of another class, let's call it A:

class B
{
    public:
       ...
       std::vector<A*> elements2;
       ...
}

C has a method that iterates through the elements of elements and elements2, and works like this:

std::vector<B*>::iterator it1;
std::vector<A*>::iterator it2;

for (it1=this->elements.begin(); it1!=this->elements.end(); ++it1)
{
    for (it2 = it1->elements2.begin(); it12=it1->elements2.end(); ++it2)
    {
        it2->do_something(); //method of class A
    }
}

But the compiler (g++) keeps telling me there is no match for operator!= in (class hierarchy).

Does anybody know what I did wrong? Other operators like '<' don't seem to work, as well.

I'm not a newbie b开发者_高级运维ut it's the first time I got to use iterators in C++ (former Python programmer) and I can't really figure out what's wrong with my code.

Thanks for the help in advance, I'm losing my hair over this!

Edit: I'm adding the whole error for reference. I edited it to fit the question, I hope I didn't mess anything up:

no match for ‘operator!=’ in ‘it1 != ((C*)this)->C::elements.std::vector<_Tp, _Alloc>::end with _Tp = B*, _Alloc = std::allocator’


You should try this :

std::vector<B*>::iterator it1;
std::vector<A*>::iterator it2;

for (it1=this->elements.begin(); it1 != this->elements.end(); ++it1)
{
    for (it2 = (*it1)->elements2.begin(); it2 != (*it1)->elements2.end(); ++it2)
    {
        (*it2)->do_something(); //method of class A
    }
}
  • In the inner loop, you tried to compare it1 (of type std::vector<B*>::iterator) with it1->elements2.end() (of type std::vector<A*>::iterator), so the compiler is right to complain.
  • You have to dereference the iterator it2 to 'reach' an element of type A* : (*it2)->do_something()

On a side note, there are probably several ways to improve your existing code, but I'll only state a few :

  • I would avoid using this->
  • Use typedef to clarify your code involving iterators
  • If it1 and it2 aren't used outside the loop, narrow their scope

You could write (obviously, the vector typedef'ed names should be more meaningful) :

typedef std::vector<A*> vector_of_A;
typedef std::vector<B*> vector_of_B;
for (vector_of_B::iterator it1 = elements.begin(), end1 = elements.end(); it1 != end1; ++it1)
{
    vector_of_A &innerVector = (*it1)->elements2;
    for (vector_of_A::iterator it2 = innerVector.begin(), end2 = innerVector.end(); it2 != end2; ++it2)
    {
        /* ... */
    }
}


This should compile:

std::vector<B*>::iterator it1;
std::vector<A*>::iterator it2;

for (it1 = elements.begin(); it1 != elements.end(); ++it1)
{
    for (it2 = elements2.begin(); it2 != elements2.end(); ++it2)
    {
        it2->do_something(); //method of class A
    }
}

But I don't know what you want to really do.


You have a vector to a pointer. As such to call a function on that pointer you have to first dereference the iterator (to get the pointer) than call the function on it.

for ( it1 = elements.begin(); it1 != elements.end(); ++it1)
{
    for (it2 = (*it1)->elements2.begin(); it2 != (*it1)->elements2.end(); ++it2)
    {
        (*it2)->do_something(); //method of class A
    }
}

Edit: I think the problem lies elsewhere. The following code compiles fine on VS2008 and VS2010

class A
{
public:
    void Fn()
    {
    }
};

class B
{
    public:
       std::vector<A*> elements2;
};

class C
{
    public:
       std::vector<B*> elements;

    void Fn()
    {
        std::vector< B* >::iterator it1;
        std::vector< A* >::iterator it2;

        for ( it1 = elements.begin(); it1 != elements.end(); ++it1 )
        {
            for ( it2 = (*it1)->elements2.begin(); it2 != (*it1)->elements2.end(); ++it2 )
            {
                (*it2)->Fn();
            }
        }
    }
};


Following code works with gcc 4.2.0 on linux. What version are you using?
Maybe its the order in which you are declaring the classes or some other issue.

#include <vector>


class A;
class B;
class C;

class A {
  public:
    void do_something() {};
};
class B
{
  public:
    std::vector<A*> elements2;
};


class C
{
  public:
    std::vector<B*> elements;

    void do_this() {
      std::vector<B*>::iterator it1;
      std::vector<A*>::iterator it2;

      for (it1=this->elements.begin(); it1!=this->elements.end(); ++it1)
      {
        for (it2 = (*it1)->elements2.begin(); it2 != (*it1)->elements2.end(); ++it2)
        {
          (*it2)->do_something(); //method of class A
        }
      }
    };
};

int main() {
  C c;
};

~
~

0

精彩评论

暂无评论...
验证码 换一张
取 消