Существует небольшое преимущество в производительности при использовании операторов предварительного увеличения. по сравнению с постинкрементными операторами. При настройке циклов, использующих итераторы, вы должны использовать предварительные приращения:
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) Кредит на связанный веб-сайт.
person
Community
schedule
03.08.2011
++it
значительно повысит эффективность. Не в вашем коде, а во времени, потраченном на объяснение людям, почему вы не сделали++it
в первую очередь. Поскольку это на самом деле не имеет ни малейшего значения, вы можете сделать это так, чтобы не возникало споров. - person Dennis Zickefoose   schedule 03.08.2011