Есть ли бесплатная версия BOOST_FOREACH? - PullRequest
3 голосов
/ 06 июля 2011

Я знаю о "подъеме" ловушки в BOOST_FOREACH, когда он кэширует конечный итератор. Однако кажется, что:

  1. Изменение последовательности в середине цикла довольно распространено (особенно push_back)
  2. Было бы нетрудно предоставить версию BOOST_FOREACH, которая не была поднята, поэтому была неуязвима для проблем модификации.

Очевидно, что в этих случаях люди часто просто пишут цикл вручную, но мой вопрос таков:

  • Существует ли такая версия? что-то вроде BOOST_FOREACH_NOHOIST или что-то подобное.

До сих пор я не смог его найти.

Примечание: отредактировано в ответ Стиву Джессопу

1 Ответ

3 голосов
/ 06 июля 2011

"Модификация последовательностей в середине цикла довольно распространена"

Избегание подъема не сделает макрос невосприимчивым к проблемам модификации, поскольку BOOST_FOREACH также использует движущийся итератор под покрытиями, которые могут быть аннулированы push_back(например, вы используете вектор, и он перераспределяет) или другие структурные изменения.Не стоит использовать новый действительный end итератор, если то, что вы сравниваете с ним, больше не является действительным.

Мне кажется разумным предоставить что-то, что очевидно имеет проблемы со структурными изменениями.Подводный камень говорит: «Если это может привести к тому, что итераторы станут недействительными, не делайте этого. Вместо этого используйте регулярный цикл for». Без указания , итераторы должны оставаться действительными.Используйте цикл for, если ваши операции могут прервать любой итератор.

Если у иногда есть проблемы, в зависимости от характера изменений, это означает, что макрос будетдолжны документировать, какие модификации в порядке, а какие нет (если только описать скрытый итератор и сказать: «Не аннулируйте это, но вы можете сделать недействительными другие итераторы»), что начинает становиться неловким API.Из выборки одного пользователя 100% предположили, что это будет невосприимчиво, поэтому я не уверен, что это очень интуитивно понятный интерфейс.

Тем не менее, я думаю, что вы правы, что BOOST_FOREACH может легко гарантировать, что он толькосодержит (1) конечный итератор, плюс (2) итератор, указывающий на текущий итератор.Таким образом, если у вас была версия без лебедки, с (2), но не с (1), тогда все, что вам нужно сделать, это убедиться, что вы не аннулируете текущий итератор.Я не думаю, что он существует, однако, автор этой ловушки, похоже, считает, что конечный итератор является частью опасности аннулирования, вместо того, чтобы пытаться отделить различные виды аннулирования.Я думаю, что BOOST_FOREACH был задуман как улучшенный синтаксис для std::for_each по сравнению с Boost.Range и соответствует этой цели.Вы всегда можете предложить соответствующим людям Boost, что это может быть больше, чем это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...