LINUX.ORG.RU

Отрицательный ответ - тоже ответ. Всем спасибо.

pathfinder ★★★★
() автор топика
Ответ на: комментарий от namezys

>кроме пары фраз о том, что объект, к которому применяются const операции считается неизменным

Ты не путаешь с тем, что const метод не может изменять данные объекта?

golodranez ★★★★
()
Ответ на: комментарий от alex_custov

> Можешь сказать, в чём проблема-то я не понимаю.

Говорят, что v.size() будет вызван только один раз, а не каждую итерацию. Следовательно в вышеприведенном коде можно выйти за границу.

Еще один пример, про который говорят, что он не валиден:

std::vector<int> v(N);
for(it = v.begin(); it != v.end(); ) {
   if(some_condition) {
      it = erase(it);
      continue;
   }
   ++it;
}
andreyu ★★★★★
()
Ответ на: комментарий от antony986

> таки да

Конструкция валидна? А вот некоторые утверждают, что нет. Но ткнуть меня носом в стандарт пока не могут.

andreyu ★★★★★
()
Ответ на: комментарий от golodranez

> Ты не путаешь с тем, что const метод не может изменять данные объекта?

МОжет я не правильно перевел, но думаю я именно так

namezys ★★★★
()
Ответ на: комментарий от andreyu

> Говорят, что v.size() будет вызван только один раз

п%здят

Еще один пример, про который говорят, что он не валиден:


erase всего-лишь делает невалидными все существующие итераторы после it - тут это не страшно, вот если-бы было добавление элемента - то да, пример был бы невалидным

ahonimous
()
Ответ на: комментарий от namezys

> Валидна. Причем тут вызываться будет каждый раз - потому что v.erase(it) изменят объект

А если я v.erase(it) заверну в какой-нибудь метод?

andreyu ★★★★★
()
Ответ на: комментарий от ahonimous

> erase всего-лишь делает невалидными все существующие итераторы после it - тут это не страшно, вот если-бы было добавление элемента - то да, пример был бы невалидным

Может вы не обратили внимание, но цикл после erase(it) не прерывается. По вашей логике я не могу двигаться дальше.

andreyu ★★★★★
()
Ответ на: комментарий от namezys

>const не обладает побочным действием на объект

не забывайте про mutable

annulen ★★★★★
()
Ответ на: комментарий от andreyu

Может вы не обратили внимание, но цикл после erase(it) не прерывается. По вашей логике я не могу двигаться дальше.

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

goose
()
Ответ на: комментарий от andreyu

> Может вы не обратили внимание, но цикл после erase(it) не прерывается. По вашей логике я не могу двигаться дальше.

вы внимательно читали? какие __существующие__ итераторы по вашему стали невалидны? если вы про end() - так он на каждой итерации получается, компилятор может сделать доброе дело в виде оптимизации - но только, если в процессе компиляции будет выяснено, что end() - действительно будет константой, и это не зависит от языка, это сам компилятор «хочет» нам помочь и он же решает - можно ли ему так схитрить

ahonimous
()
Ответ на: комментарий от goose

> >Может вы не обратили внимание, но цикл после erase(it) не прерывается. По вашей логике я не могу двигаться дальше.

Не можешь. При удалении последнего элемента случится писец и вообще это быдлокод.


При удалении последнего элемента erase(it) вернет it == end(), и цикл на этом закончится.

Не думаю, что написавший его предполагал то, что он делает.


Думаю, вы не прочитали код.

andreyu ★★★★★
()
Ответ на: комментарий от ahonimous

> вы внимательно читали?

Вы это мне?

какие __существующие__ итераторы по вашему стали невалидны?


По моему, итератор будет валиден, т.к. он на каждой итерации получается заново.

если вы про end() - так он на каждой итерации получается,


Об этом и речь. Имеет ли право компилятор сделать оптимизацию таким образом, что бы вызов end() был сдела только один раз, а не каждую итерацию?

компилятор может сделать доброе дело в виде оптимизации - но только, если в процессе компиляции будет выяснено, что end() - действительно будет константой, и это не зависит от языка, это сам компилятор «хочет» нам помочь и он же решает - можно ли ему так схитрить


Так вот я и спрашиваю, имеет ли такое право компилятор? Если имеет, то ткните меня носом в стандарт.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

> имеет ли такое право компилятор?

компилятор имеет право делать все, что ему хочется, если это не нарушит логику работы, изначально мы не сказали ему запоминать результат end(), потому компилятор может это сделать сам - но в 23.2.4.3 явно указывается, что если внутри цикла будет erase, то end() станет невалидный, и следоватьно, если компилятор начхает на это - то это будет и нарушение правил описанных в стандарте и очевидный баг, т.к. правильный код на С++ компилятор превратил в невалидный

ahonimous
()
Ответ на: комментарий от ahonimous

> но в 23.2.4.3 явно указывается, что если внутри цикла будет erase, то end() станет невалидный, и следоватьно, если компилятор начхает на это - то это будет и нарушение правил описанных в стандарте и очевидный баг, т.к. правильный код на С++ компилятор превратил в невалидный

Вот, это именно то, что мне нужно. GCC в таких случаях даже с -O3 делает все корректно. Если компилятор от MS забивает на этот пункт, то ну его нафиг, такой компилятор.

andreyu ★★★★★
()
Ответ на: комментарий от dt1

потому что у твоего метода size() имеется побочный эффект в виде вызова левой функции std::cout.operator<<

убери вывод на экран, поставь бряку, и о чудо xD. метод size() вызовется один раз.

там свои плюшки короче, про конст - прогнали тут, точно по стандарту как не помню, но все дело в вызове std::cout.operator<< (т.к. он может иметь side effects)

anonymous
()
Ответ на: комментарий от dt1

<off>млять, походу придется регицо на лоре... оптравлял сообщение, походу капчу неверно заполнил, страницу не посмотрев закрыл быстро - не ушло сообщение.</off>

все дело в вызове std::cout.operator<<. поэтому компилер _НЕ_ИМЕЕТ_ПРАВА_ оптимизировать. по стандарту как не помню точно... толи от того что у нас cout с его методом не конст... толи еще почему.. суть: std::cout.operator<< может иметь сайд-эффекты, поэтому компилер не имеет права пропускать вызовы твоего size().

убери вывод на экран из функции, поставь на функцию бряку, посмотри количество выводов. вуаля )

anonymous
()
Ответ на: комментарий от Love5an

Вообще, const стоит воспринимать навроде как комментарии.

const - дает инструкцию компилятору что эта переменная неизменяемая

enep ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.