Понятие разницы между оператором до и после приращения для STL - PullRequest
7 голосов
/ 15 сентября 2011

Возможно:

for (vector<int>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter)
{}

Я понимаю разницу, когда дело доходит до / после приращения для встроенных типов, таких как int и т. Д., Но с точки зрения итератора, какая разница между ++iter и iter++? (Имейте в виду, что я знаю, что оба дают здесь один и тот же результат).

Ответы [ 5 ]

9 голосов
/ 15 сентября 2011

++iter, скорее всего, будет быстрее, но никогда не медленнее, чем iter++.

Для реализации оператора постинкремента iter++ необходимо сгенерировать дополнительный временный объект (это временное значение возвращается обратно, в то время как оригинал iter увеличивается ++) по сравнению с реализацией оператора постинкремента ++iter, поэтому, если компилятор Оптимизируйте (да, это может) увеличение поста, тогда ++iter, скорее всего, будет быстрее, чем iter++.

Учитывая вышеизложенное, всегда предпочтительно использовать ++iter в условиях зацикливания.

4 голосов
/ 15 сентября 2011

Это означает то же самое, что и целое число.

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

Для постинкремента iter должен быть скопирован во временный файл, затем iter увеличивается, копия возвращается. Однако большинство компиляторов могут оптимизировать тот факт, что эта копия не используется, и, таким образом, копию можно удалить, сделав ее такой же, как и перед приращением.

Для тех компиляторов, которые не могут, постинкремент может привести к несколько более медленному предварительному исполнению, но это больше не так.

3 голосов
/ 15 сентября 2011

Все зависит от того, как они реализованы.

Но наиболее распространенным способом реализации постинкремента является предварительное увеличение с дополнительной копией.

class MyIter
{
    // Definition of pre-increment:
    //    ++object;
    MyIter& operator++()
    {
        /* Increment the iterator as appropriate
           You should be changing the object in place
         */


        // Once you are done return yourself.
        return *this;
    }
    // Definition of post-increment:
    //    object++;
    MyIter operator++(int)
    {
        // Post increment (returns the same value) so build the result.
        MyIter  result(*this);

        // Now do the increment using pre-increment on the current object
        ++(*this);

        // return the result.
        return result;
    }
};

Таким образом, стандартная реализация вызовов постинкрементного преинкремента и дополнительно делает копию объекта. Обратите внимание, что при возврате также существует дополнительная конструкция копии, но обычно она компилируется компилятором.

Примечание: предварительное увеличение, поскольку оно влияет на один и тот же объект, обычно возвращает ссылку на свой элемент (то есть, не стоимость при возврате).

2 голосов
/ 15 сентября 2011

Разница в том, что они не дают одинакового результата, в то время как этот конкретный пример будет делать то же самое независимо от используемой формы приращения. Форма предварительного увеличения сначала увеличивает значение, а затем возвращает его; тогда как постинкрементная форма увеличивает результат, но возвращает значение, предшествующее приращению. Обычно для базовых типов это бесплатно, но для таких вещей, как итераторы, требуется создать временное значение для хранения неинкрементного значения, чтобы потом было возвращено.

2 голосов
/ 15 сентября 2011

В общем случае предварительное увеличение обычно предпочтительнее, чем последующее увеличение, поскольку может учитывать некоторую оптимизацию, которая может избежать создания временных. Как именно это реализовано, зависит от STL, включенного в ваш компилятор.

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