Приоритет оператора в C++ отличаются для указателей и итераторов?

Код ниже демонстрирует это различие:

#include <iostream>
#include <string>

int main()
{
        char s[] = "ABCD";
        std::string str(s);

        char *p = s;
        while(*p) {
                *p++ = tolower(*p);          // <-- incr after assignment
        }
        std::cout << s << std::endl;

        std::string::iterator it = str.begin(), end = str.end();
        while(it != end) {
                *it++ = tolower(*it);        // <-- incr before assignment ?
        }
        std::cout << str << std::endl;

        return 0;
}

это производит вывод:

abcd
bcd

если мы разделяем операцию присвоения и увеличиваем оператор:

while(it != end) {
  *it = tolower(*it);        // <-- incr before assignment ?
  it++;
}

вывод будет как ожидалось.

Что случилось с исходным кодом?

$ g++ --version
g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
Copyright (C) 2004 Free Software Foundation, Inc.
6
задан Oleg Razgulyaev 28 May 2010 в 09:14
поделиться

3 ответа

Проблема в том, что порядок вычисления аргументов operator = не указан. Это соответствует стандарту C ++ 5.2.2 / 8. Рассмотрим следующее:

*it++ = tolower(*it);

равно

operator=( *it++, tolower(*it) );

Теперь * it ++ может быть вычислено до tolower (* it) и наоборот.

9
ответ дан 8 December 2019 в 18:33
поделиться

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

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

*p++ = tolower(*p);

*it++ = tolower(*it);

Вам необходимо переформулировать это утверждение таким образом, чтобы определить последовательность. Я предполагаю, что вы хотите что-то вроде этого.

char c = tolower(*p);
*p++ = c;
2
ответ дан 8 December 2019 в 18:33
поделиться
*it++ = tolower(*it); 
*p++ = tolower(*p);

Обе эти строки вызывают неопределенное поведение. Вы не можете изменить значение переменной более одного раза в одном операторе (++ изменяет один раз, operator = изменяет дважды).

Поэтому неудивительно, что вы получаете разные значения.

2
ответ дан 8 December 2019 в 18:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: