Существует небольшое преимущество в производительности при использовании операторов предварительного увеличения по сравнению с операторами последующего увеличения. При настройке циклов, использующих итераторы, вы должны использовать предварительные приращения:
for (list<string>::const_iterator it = tokens.begin();
it != tokens.end();
++it) { // Don't use it++
...
}
Причина выясняется, когда вы думаете о том, как обычно будут реализованы оба оператора. Предварительное увеличение довольно просто. Однако для того, чтобы постинкремент работал, вам необходимо сначала сделать копию объекта, выполнить фактическое увеличение для исходного объекта, а затем вернуть копию:
class MyInteger {
private:
int m_nValue;
public:
MyInteger(int i) {
m_nValue = i;
}
// Pre-increment
const MyInteger &operator++() {
++m_nValue;
return *this;
}
// Post-increment
MyInteger operator++(int) {
MyInteger clone = *this; // Copy operation 1
++m_nValue;
return clone; // Copy operation 2
}
}
Как видите, реализация после инкремента включает в себя две дополнительные операции копирования. Это может быть довольно дорого, если рассматриваемый объект громоздок. Сказав это, некоторые компиляторы могут быть достаточно умны, чтобы выполнить оптимизацию с помощью одной операции копирования. Дело в том, что постинкремент обычно включает в себя больше работы, чем преинкремент, и поэтому разумно привыкнуть помещать ваши «++» перед итераторами, а не после.
(1) Кредит на связанный сайт.