При использовании внутри цикла for, есть ли исключение или даже крайний случай, когда постинкремент действительно лучше, чем преинкремент?

Рассмотрим следующие утверждения:

for (Container<Object>::Iterator it = container.begin(); it != container.end(); it++) {
*loop_content*
}

против

for (Container<Object>::Iterator it = container.begin(); it != container.end(); ++it) {
*loop_content*
}

Насколько я понимаю, независимо от того, что такое * loop_content *, при использовании внутри цикла for, как в примере выше, версия с прединкрементом гарантированно будет не хуже чем постинкрементная версия. Есть ли какое-то исключение или даже крайний крайний случай, когда это утверждение больше не соответствует действительности и что постинкремент действительно лучше чем преинкремент?

Если не так, вот мой немного не по теме Второй вопрос, который меня интересовал годами: почему во многих учебниках люди учатся использовать цикл for, например:

for (int i = 0; i < 42; i++)

не

for (int i = 0; i < 42; ++i)

Я предполагаю, что есть некоторые средневековые языки, в которых реализован только i ++, но не ++, так что люди, привыкшие к этим языкам, следуют тому, как они увеличивают итераторы, но я действительно хочу знать, откуда взялась эта конвенция.

0

Решение

Обычно постинкремент и преинкремент отличаются только в двух отношениях: они возвращают другое значение, а постинкремент немного дороже, потому что он требует создания копии переменной. Возвращаемое значение не используется в for цикл, поэтому, если мы хотим, чтобы пост-лучше, чем раньше, мы должны изобрести новый Container класс чей Iterator имеет странный и дорогой оператор предварительного увеличения. Что-то вроде

operator++()
{
ptr = ptr->next;
// perform some undefined behavior, or just hash the Beijing telephone book
return *this;
}

Это может быть сделано в результате простой некомпетентности. Что касается реальный причина положить что-то плохое в operator++()Я в тупике.

Постскриптум Однажды у меня был подчиненный, который настаивал на том, что постинкремент был правильным, и что использование преинкремента в for Цикл даст разные (неправильные) результаты. Повторное исправление его не помогло; тот факт, что он мог иметь проверенный эта гипотеза очень легко не имела никакого значения. Каким-то образом он работал инженером-программистом более десяти лет, но у него ничего не получалось.

1

Другие решения

Чтобы уточнить мой комментарий, for петля как

for (pre; cond; post) body

эквивалентно следующему while петля

{
pre

while (cond)
{
body
post
}
}

Как видите, post часть, а внутри while тело цикла, отдельно от for тело петли.

2