Ниже несколько «зло», но это спасло нас от многих ошибок.
(Обновление, благодаря комментарию @ Ricky65 для привлечения меня сюда.) C++ 11 имеет range-based for loop, который намного превосходит его, если ваш компилятор поддерживает его; мы по-прежнему работаем с некоторыми действительно старыми компиляторами.
#define FOREACH(iter,stlContainer) \
for (typeof(stlContainer.begin()) iter = stlContainer.begin(), \
iter##End_Cached = stlContainer.end(); \
iter != iter##End_Cached; \
++iter)
(Дальнейшее обновление, кредит в подпиточных дэв.) Это свободно основано на более сложное, но более способное BOOST_FOREACH
макроса, но имеет преимущество быть гораздо легче пошагова в отладочной версии для дел, и не требуя небольшой кучи форвардных заголовков (которые в некоторых кодовых базах/группах являются verboten).
Использование std::for_each
обычно предпочтительнее, но имеет некоторые недостатки:
- пользователи должны знать много о взаимодействиях между
bind1st
/bind2nd
/ptr_fun
/mem_fun
эффективно использовать его для нетривиального «посещения» - boost исправляет многие из этих проблем, но не у всех есть или нет стимулов для пользователей, которым может понадобиться отдельный функтор (как правило, структура) только для одной точки использования; указанные структуры не могут быть объявлены внутри функции, окружающей цикл, что приводит к «нелокальности» связанного кода - он не читается, а также имеет логическую последовательность с потоком остальной функции в некоторых случаях
- это не всегда хорошо инлайн, в зависимости от компилятора
FOREACH макрос, как указано выше, дает несколько вещей:
- как
std::for_each
, вы не получите ваши граничные испытания неправильно (no iterating one past the end и т. д.)
- он будет использовать
const_iterators
над постоянными контейнерами
Обратите внимание, что для этого требуется несколько нестандартное расширение «typeof».
Типичное использование может быть:
list< shared_ptr<Thing> > m_memberList;
// later
FOREACH(iter, m_memberList)
{
if ((*iter)->getValue() < 42) {
doSomethingWith(*iter);
}
}
Я не совсем доволен этим макросом, но это было бесценным здесь, особенно для программистов, не столько опыта в STL-курсе дизайна.
(Пожалуйста, не стесняйтесь указать плюсы/минусы/недостатки, я буду обновлять ответ.)
Я считаю этот вопрос очень полезно. Тем не менее, он управляется некоторыми бесполезными ответами ... +1 всем, кто внес свой вклад. – AndreasT