Здравствуйте, netch80, Вы писали:
EP>>Моя позиция в том, что лучше иметь разные варианты решений в своём инструментарии, особенно если у них есть уникальные плюсы, а не слепо отвергать их из-за каких субъективных предрассудков.
N>Эти "субъективные предрассудки" превращаются в объективные, когда начинаешь смотреть, как воспринимает такой код не только тот, кто всю жизнь "в системе", как я, а и, например, типовой юниор, часто к тому же перешедший с какого-то соседнего языка.
Ну давай рассмотрим этот сценарий. Как по-твоему ведёт себя юниор впервые увидевший
while(n--)?
EP>>За всякими хаками частенько стоит набор аксиом, концепций, теорем — и то что выглядит на первый взгляд как хак, на самом деле имеет под собой вполне строгую математику
N>Имеет, да. Но читаешь всё равно шаблонами. И шаблон типа for i in closed_range(n-1, 0, -1) будет читаться проще всегда, чем while(n--).
Это пока шаблона
while(n--) нет в голове.
Да и что означает closed_range в данном случае? запрет на n=0?
EP>>Ваше благородие, соизвольте заглянуть в ядро Linux следующим grep'ом: grep -r 'while\s*(\s*[:alnum:]_]*\s*--\s*).*[^;]'
N>Ну я больше имел в виду варианты типа (for(...;i-->0;...). Если это все случаи, то их мало и я на них таки не натыкался. Ядро таки огромное, 1148 это копейки, можно ни разу не встретить. Но учту.
Ну я говорю всё время про
while(n--), но можем конечно и вариант с for погрепать. Но суть от этого не меняет — применяется повсеместно.
EP>>>>Идиома, кстати, применима и к итераторам — у которых может даже и не быть operator<
N>>>От замены в аналоге "i-->1" на "i--!=1" теряется только визуальная красота стрелки.
EP>>А я не об этом. Я о том что вот этот вариант: for (int i=n-1; i>=0; --i) на итераторы не переносится в общем случае, из-за отсутствия отношения порядка и one-before-last. А вариант while(it-- != first) — работает, потому что requires более общие concepts. Вот такой вот "хак".
N>Эээ
N>вы вообще-то не имеете права декрементировать итератор, равный begin() или rbegin(). Может случиться что угодно.
Да, сам увидел — я это место дополнил:
Точнее one-before-last обходится переносом декремента на первую строчку тела (как уже показывали ранее в этой теме): while(it != first){--it; ...}, но концептуально то же самое.
N>Оптимизатор всё равно для типовых случаев вроде плоского массива всё это заоптимизирует.
Не всегда варианты простые. Тем не менее — прямее сразу делать оптимально по-возможности жеж.
N>А через ФВП всё равно получится менее удобно, чем при поддержке foreach самим компилятором.
Ну это скорее вопрос к синтаксису замыканий и их возможностей. Радикальное отличие for_each+замыкание от range-based-for — только в return/break/continue, остальное синтаксический сахар.