Задача C ++ STD Операторы сравнения итераторов - PullRequest
2 голосов
/ 22 ноября 2010

Добрый день, господа,

потому что, похоже, мой не будет таким хорошим.

У меня есть класс C, который не имеет дочерних элементов, но имеет вектор из указателей на экземпляры другого класса, назовем его B:

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

B также имеет вектор указателей на экземпляры другого класса, назовем его A:

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

C имеет метод, который перебирает элементы элементов и elements2 и работает так:

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
    }
}

Но компилятор (g ++) постоянно говорит мне, что нет совпадения для оператора! = In (иерархия классов).

Кто-нибудь знает, что я сделал не так? Другие операторы вроде '<' тоже не работают. </p>

Я не новичок, но я впервые использую итераторы в C ++ (бывший программист Python), и я не могу понять, что не так с моим кодом.

Заранее спасибо за помощь, я теряю волосы из-за этого!

Редактировать: я добавляю всю ошибку для справки. Я отредактировал это, чтобы соответствовать вопросу, я надеюсь, что я ничего не испортил:

нет совпадения для 'operator! =' В 'it1! = ((C *) this) -> C :: elements.std :: vector <_Tp, _Alloc> :: заканчивается _Tp = B *, _Alloc = станд :: распределитель '

Ответы [ 4 ]

4 голосов
/ 22 ноября 2010

Вы должны попробовать это:

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
    }
}
  • Во внутреннем цикле вы пытались сравнить it1 (типа std::vector<B*>::iterator) с it1->elements2.end() (типа std::vector<A*>::iterator), поэтому компилятор вправе жаловаться.
  • Вы должны разыменовать итератор it2, чтобы «добраться» до элемента типа A*: (*it2)->do_something()

Кстати, есть несколько способов улучшить существующий код, но я приведу лишь несколько:

  • Я бы не стал использовать this->
  • Используйте typedef для уточнения кода с использованием итераторов
  • Если it1 и it2 не используются вне цикла, сузьте область их применения

Вы можете написать (очевидно, что имена typedef 'должны быть более значимыми):

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)
    {
        /* ... */
    }
}
1 голос
/ 22 ноября 2010

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

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
    }
}

Редактировать : Я думаю, проблема в другом. Следующий код прекрасно компилируется на VS2008 и 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();
            }
        }
    }
};
1 голос
/ 22 ноября 2010

Это должно скомпилироваться:

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
    }
}

Но я не знаю, что вы действительно хотите сделать.

0 голосов
/ 22 ноября 2010

Следующий код работает с gcc 4.2.0 на linux.Какую версию вы используете?
Возможно, это порядок, в котором вы объявляете классы, или какая-то другая проблема.

#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;
};

~
~

...