Изменение членов объекта через итератор? - PullRequest
1 голос
/ 17 декабря 2010

Прошло много времени с тех пор, как я использовал C ++. Могу ли я сделать что-то подобное?:

for (vector<Node>::iterator n = active.begin(); n!=active.end(); ++n) {
  n->ax /= n->m;
}

где Node - это объект с несколькими поплавками в нем?

Если я пишу на Java, то я пытаюсь сделать что-то похожее на:

for (Node n : this.active) {
  n.ax /= n.m;
}

, где активным является массив списков объектов Node.

Кажется, я забыл какую-то причуду прохождения по ссылке или что-то еще в отчаянии вскидывает руки

Ответы [ 6 ]

1 голос
/ 17 декабря 2010

Да. Этот синтаксис в основном работает почти для всех контейнеров STL.

// this will walk it the container from the beginning to the end.
for(container::iterator it = object.begin(); it != object.end(); it++)
{
}

object.begin() - в основном дает итератору первый элемент контейнера.

object.end() - итератор устанавливается на это значение после прохождения всех элементов. Обратите внимание, что для проверки конца мы использовали !=.

operator ++ - Переместить итератор к следующему элементу.

В зависимости от типа контейнера у вас могут быть другие способы навигации по итератору (скажем, назад, в произвольном порядке в определенном месте контейнера и т. Д.) Хорошее введение в итераторы: здесь .

1 голос
/ 17 декабря 2010

Краткий ответ: да, вы можете.

Итератор является прокси для элемента контейнера. В некоторых случаях итератор буквально просто указатель на элемент.

0 голосов
/ 17 декабря 2010

Что у вас будет работать.Вы также можете использовать один из многих алгоритмов STL для достижения той же цели.

std::for_each(active.begin(), active.end(), [](Node &n){ n.ax /= n.m; });
0 голосов
/ 17 декабря 2010

В случае std::vector, да, вы можете манипулировать объектом, просто разыменовывая итератор. В случае отсортированных контейнеров, таких как std::set, вы не можете этого сделать. Поскольку набор вставляет свои элементы по порядку, прямое манипулирование содержимым недопустимо, так как это может испортить порядок.

0 голосов
/ 17 декабря 2010

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

Однако вы можете подумать о том, что если вы измените контейнер (скажем, удалив или переместив элемент), то существующие итераторы могут быть недействительными, в зависимости от контейнера и выполняемой операции. и сведения об задействованных итераторах (именно поэтому вам не разрешено изменять «ключ» объекта в ассоциативном контейнере - это может потребовать перемещения объекта в контейнере в общем случае).

0 голосов
/ 17 декабря 2010

Ваш код отлично работает для меня

#include <vector>
using std::vector;
struct Node{
  double ax;
  double m;
};

int main()
{
  vector<Node> active;
  for (vector<Node>::iterator n = active.begin(); n!=active.end(); ++n) {
    n->ax /= n->m;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...