Считается ли инициализация итератора внутри цикла циклом плохим стилем и почему? - PullRequest
11 голосов
/ 10 октября 2008

Как правило, вы найдете код STL следующим образом:

for (SomeClass::SomeContainer::iterator Iter = m_SomeMemberContainerVar.begin(); Iter != m_SomeMemberContainerVar.end(); ++Iter)
{
}

Но на самом деле у нас есть рекомендация написать это так:

SomeClass::SomeContainer::iterator Iter = m_SomeMemberContainerVar.begin();
SomeClass::SomeContainer::iterator IterEnd = m_SomeMemberContainerVar.end();
for (; Iter != IterEnd; ++Iter)
{
}

Если вас беспокоит область видимости, добавьте фигурные скобки:

{
    SomeClass::SomeContainer::iterator Iter = m_SomeMemberContainerVar.begin();
    SomeClass::SomeContainer::iterator IterEnd = m_SomeMemberContainerVar.end();
    for (; Iter != IterEnd; ++Iter)
    {
    }
}

Это должно дать выигрыш в скорости и эффективности, особенно если вы программируете консоли, потому что функция .end () не вызывается на каждой итерации цикла. Я просто считаю улучшение производительности само собой разумеющимся, оно звучит разумно, но я не знаю, насколько оно сильно, и оно, безусловно, зависит от типа контейнера и фактической реализации STL. Но, используя этот стиль пару месяцев, я все равно предпочитаю его первому.

Причина читабельности: строка for аккуратна и опрятна. С квалификаторами и переменными-членами в реальном производственном коде очень просто иметь длину действительно для строк, если вы используете стиль в первом примере. Вот почему я намеренно сделал так, чтобы в этом примере была горизонтальная полоса прокрутки, просто чтобы вы поняли, о чем я говорю. ;)

С другой стороны, вы неожиданно вводите переменные Iter во внешнюю область цикла for. Но тогда, по крайней мере, в среде, в которой я работаю, ИТЭР был бы доступен во внешней области даже в первом примере.

Что вы думаете об этом? Существуют ли какие-либо плюсы в первом стиле, кроме ограничения возможностей Iter?

Ответы [ 13 ]

0 голосов
/ 10 октября 2008

Я согласен с Ферруччо. Некоторые могут предпочесть первый стиль, чтобы вытащить вызов end () из цикла.

Могу также добавить, что C ++ 0x фактически сделает обе версии намного чище:

for (auto iter = container.begin(); iter != container.end(); ++iter)
{
   ...
}

auto iter = container.begin();
auto endIter = container.end();
for (; iter != endIter; ++iter)
{
   ...
}
0 голосов
/ 10 октября 2008

Мне кажется, что второй вариант более читабелен, поскольку у вас нет одной гигантской строки. Тем не менее, Ферруччо поднимает хороший вопрос о масштабах.

0 голосов
/ 10 октября 2008

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

...