есть ли более симпатичный синтаксис для итератора с ++? - PullRequest
6 голосов
/ 16 августа 2011

Есть ли более симпатичный / менее многословный способ использования итераторов в C ++? Из руководств, которые я видел, я либо устанавливал typedef везде (что утомительно делать для многих одноразовых циклов for):

typedef std::vector<std:pair<int, int> >::iterator BlahIterator;

или имеют многословные петли, похожие на:

for (std::vector<std:pair<int, int> >::iterator it = ... ) ...

Есть ли лучший способ?

Ответы [ 7 ]

7 голосов
/ 16 августа 2011

В C ++ 11 вы можете использовать основанный на диапазоне цикл for в сочетании с ключевым словом auto:

for (auto& it : v) ...
4 голосов
/ 16 августа 2011

С boost вы можете использовать макрос FOR_EACH .

typedef pair<int, int> tElem;
BOOST_FOREACH( tElem e, aVector )
{
    cout << e.first << " " << e.second << '\n';
}
2 голосов
/ 16 августа 2011

С c ++ 0x вы можете использовать ключевое слово auto:

for (auto i = v.begin(); i != v.end(); ++i) {}
2 голосов
/ 16 августа 2011

Алгоритмы как бы решают эту конкретную проблему.
Особенно с новыми лямбда-функциями.

std::for_each(c.begin(), c.end(), Action()); /* Where Action is your functor */

Или с лямбдой:

std::for_each(c.begin(), c.end(), [](type const& e) { /* Stuff */ });

Примечание: непопасть в ловушку использования std :: for_each для замены всех циклов.Существует целый ряд алгоритмов, использующих итераторы, которые позволяют вам манипулировать или выполнять операции на основе содержимого контейнера.

1 голос
/ 16 августа 2011

Я обычно использую следующий шаблон именования:

typedef std::pair<int, int> Blah;
typedef std::vector<Blah> Blahs;

, а затем использую Blahs::iterator, то есть я называю не итератор, а контейнер (и обычно то, что в нем содержится).
typedef - очень полезный механизм абстракции.

Обратите внимание, что вектор "Blah" называется "Blahs" (т.е. просто множественное число), а не "BlahVector", потому что конкретный контейнер не имеет значения.

0 голосов
/ 16 августа 2011

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

template <class T>
do_something(T begin, T end) { 
    for (T pos = begin; pos != end; ++pos) 
        do_something_with(*pos);
}
0 голосов
/ 16 августа 2011

Я обычно определяю это, хотя мне сказали, что я попаду в ад:

#define forsn(i, s, n) for(int i = (s); i < (n); ++i)
#define forn(i, n) forsn(i, 0, n)
#define forall(it, g) for(typeof g.begin() it = g.begin(); it != g.end(); ++it)

Затем, чтобы выполнить цикл от 0 до n, обычную задачу, я говорю forn(i, n) foo(i);, и цикл любого стандартного контейнера c, я говорю forall(it, c) foo(it); Обратите внимание, что typeof является расширением GCC для стандарта.

...