При чем тут деградация? ijk — стандартные математические индексы, которые были примерно всегда. Не во времена шумеров, но до появления ЭВМ. А вы говорите, что их родоначальником был Фортран, что неверно. За это поставили минусы. В чем проблема-то?
Это жонглирование словами. «люди из внешнего мира» = «люди, пришедшие из внешнего мира». И я сказал как раз о процессе перехода. Не говоря уже о том, что человек может писать на десятке языков, включая С++. Если он — не основной, то тоже можно говорить о «внешнем мире».
Можно код глянуть, но влом чета) Думаю просто не стали заморачиваться, итераторы на стандартных контейнерах сводятся к чистой арифметики указателей.
Нет, просто по стандарту, насколько я понял, итератор должен позволять делать dereference, чтобы выполнять операцию инкремента. Это понятно — если у нас, скажем, линейный список, нам нужно, чтобы элемент дереференсился, чтобы найти адрес следующего. Но .end специальный вид итератора, для которого можно было (по идее, я могу ошибаться, мне было бы интересно, почему) определить операцию инкремента как всегда выдающую сам .end, потому что нет разницы, мы шагнули за пределы контейнера на 1 элемент, или на 100 — все равно выдаем .end, как признак выхода за пределы.
А почему it < v.end() design flaw совсем не понял
Не "<" design flaw, а то, что двойной инкремент может привести к UB.
по моему все логично — меньше последнего адреса
Так .end не последний адрес, а заведомо невалидный, после последнего.
И в Бэйсике и в Фортране подпрограммы называются SUBROUTINE
Вот только незадача: да, есть такие диалекты Бейсика, где подпрограммы называются SUB, например, тот же Quick Basic. Однако, ветка началась с вашего высказывания о том, что-де Бейсик создан для обучения Фортрану и очень на него похож. Однако ж в том Бейсике, и в большинстве более поздних диалектов такого конструкта как «подпрограмма» нет вообще. Точнее, нет в привычном нам понимании. Есть только блок кода с метками, который вызывается GOSUB, почти как GOTO, с доступом ко всем переменным, без разграничения области видимости. Как в машинном коде. Например:
940 GOTO 1000
950 LET a = 3
…
…
990 RETURN
1000 FOR i = 1 to 10
1010 GOSUB 950
1020 NEXT i
В то время как и в Ф. и в П. есть привычные нам подпрограммы, пусть они и обозначаются разными ключевыми словами.
Согласитесь, приведенное мною отличие намного важнее разницы в ключевых словах.
Оператор PRINT имеется и в Бэйсике и в Фортране
Есть, но делает он несколько иное. Это тот же вывод «в устройство». Не каждый диалект Фортрана разрешит вам использовать PRINT с произвольным форматом и выводом «по умолчанию».
write Паскаля много ближе Бейсиковскому PRINT'у — здесь отличие по факту только в скобках и названии оператора.
… и так далее => программу на Бэйсике достаточно лишь немного подправить чтобы она смогла откомпилироваться на Фортране, а вот для Паскаля придётся практически всё переписывать.
Это разница в названии операторов и синтаксисе. Это мелочь, поймите — концептуальная разница где-то меньше между П и Ф, где-то между П и Б. Но практически везде велика между Ф и Б.
Я все же напишу примеры как-нибудь, надо настроить среды для Ф и Б.
Это, кстати, вполне себе design flaw. Если использовать контейнер с непосредственным доступом и ограничением по номеру элемента вида " < v.count()", это будет работать одинаково для любых проходов.
Мне не совсем понятня механика в данном случае: насколько я понимаю STL, .end() — особый вид итератора, который невалиден и располагается за последним элементом. Мы предполагаем здесь, что при двойной инкрементации мы можем попасть в зацикливание. Что происходит при инкрементации итератора .end()?
—
calling this function might result in undefined behavior because calling operator ++ for the end of a sequence is not defined
Ага, ну тогда ясно. Непонятно, почему не сделать так, что инкремент .end()'а давал бы тот же .end().
В «негибких» никто, ну просто вообще никто не мешает делать то же самое на while циклах (+-). А цикл for, как именно цикл со счетчиком, для людей «из внешнего мира» выглядит не гибко, а дико. Технопрон.
Объявление i до цикла ломает стройность кода — первая секция for остаётся пустой, что заставляет читателя вдумываться в код выше, пытаясь понять то ли это ошибка, то ли так и было надо.
Что-что?
Кто мешает сделать
void abc() {
int i;
..
..
..
for (i = 0; i <= 10; i++){
}
}
Проверка условия находится во втором блоке, чтобы подчеркнуть тот факт, что она будет выполняться при первой итерации цикла сразу после инициализации счётчика i — только при этом объяснении всё выглядит более-менее логично
Нет, не только. Это стандартное объявление в самых разных ЯП аж с Фортрана: начало, конец и приращение.
долг перед самим собой это как?
какая-то часть вас одолжила что-то у другой части вас?
Нет, это ты сам одолжил у себя в другом времени. У себя завтрашнего, например. Ценность знаний, так же, как и денег, зависит от времени.
тогда это не долг а шизофрения (или другой подтип раздвоения личности).
Человек постоянно исполняет множество социальных ролей, здесь нет никакого болезненного раздвоения. И да, одна социальная роль может одолжить у другой; не буквально, а в рамках модели. Ты вчера и ты сегодня — это разные люди.
я понимаю обещание самому себе что-то сделать в будущем. но понятие долг сюда никаким боком не уместно
Это означает, что вы слово «долг» понимаете иначе, чем автор статьи. Только и всего. Для автора, судя по всему, (и для меня) «взять в долг у себя завтрашнего» — вполне нормальная фраза.
Ну, не знаю, мне кажется, что новичок вполне может сразу гуй писать. Это студенту такое не дадут, а заставят до посинения писать алгоритмы сортировки, но студент != новичок.
Вы под новичком, видимо, имеете в виду начинающего профессионального разработчика, я — изучающего язык. Тот, кто «уже не студент», тем более будет знать обсуждаемую особенность. Я думал, мы говорим о начинающих.
Как же не сожрёт, когда сожрёт? :) И размер объекта вырастет:
И производительность ухудшится (накладные расходы на походы в vtable
Хоспаде, очевидно же, что речь не про «с нулевыми в абсолютном выражении накладными расходами».
Выводить текст каринкой, например, — это не стандарт. Делать переход по страницам/пунктам меню без изменения адреса, так что нельзя дать сохранить ссылку на страницу — это не стандарт.
Попробуйте представить, что вы зелёный новичок, а я попробую рассказать, как он может воспринимать это место в C++.
Это уже не очень хорошее начало. Потому что виртуальный деструктор, о котором мы говорим, нам понадобится, если мы собираемся удалять объект по ссылке на его родительский тип, т.е. например если мы заносим его в коллекцию, которая контроллирует время жизни объекта. Например, это какие-то control'ы (виджеты, итп) и нам надо их занести в список «контролы окна», по которому мы будем потом проходить и в случае «чего» удалять их безотносительно внутренней реализации. Это уже не для новчика.
но при этом и в голову не придёт, что то же самое может быть нужно для деструктора
Странно; все книжки по «плюсам», которые я читал, всегда оговаривают последовательность вызова деструкторов, из которой ясно, как оно будет работать при вызове деструктора родительского класса.
Это, конечно, может быть проблемой — я, пожалуй, спишу на субъективность, как и то, что С++ — не мой основной язык, и не первый ООП язык для меня. Мне кажется, что достаточно понимать последовательность вызова д-в и придерживаться простого правила — не уверен, сделай д. вирутальным. Ресурсов это не сожрет.
Нет, просто по стандарту, насколько я понял, итератор должен позволять делать dereference, чтобы выполнять операцию инкремента. Это понятно — если у нас, скажем, линейный список, нам нужно, чтобы элемент дереференсился, чтобы найти адрес следующего. Но .end специальный вид итератора, для которого можно было (по идее, я могу ошибаться, мне было бы интересно, почему) определить операцию инкремента как всегда выдающую сам .end, потому что нет разницы, мы шагнули за пределы контейнера на 1 элемент, или на 100 — все равно выдаем .end, как признак выхода за пределы.
Не "<" design flaw, а то, что двойной инкремент может привести к UB.
Так .end не последний адрес, а заведомо невалидный, после последнего.
Вот только незадача: да, есть такие диалекты Бейсика, где подпрограммы называются SUB, например, тот же Quick Basic. Однако, ветка началась с вашего высказывания о том, что-де Бейсик создан для обучения Фортрану и очень на него похож. Однако ж в том Бейсике, и в большинстве более поздних диалектов такого конструкта как «подпрограмма» нет вообще. Точнее, нет в привычном нам понимании. Есть только блок кода с метками, который вызывается GOSUB, почти как GOTO, с доступом ко всем переменным, без разграничения области видимости. Как в машинном коде. Например:
940 GOTO 1000
950 LET a = 3
…
…
990 RETURN
1000 FOR i = 1 to 10
1010 GOSUB 950
1020 NEXT i
В то время как и в Ф. и в П. есть привычные нам подпрограммы, пусть они и обозначаются разными ключевыми словами.
Согласитесь, приведенное мною отличие намного важнее разницы в ключевых словах.
Есть, но делает он несколько иное. Это тот же вывод «в устройство». Не каждый диалект Фортрана разрешит вам использовать PRINT с произвольным форматом и выводом «по умолчанию».
write Паскаля много ближе Бейсиковскому PRINT'у — здесь отличие по факту только в скобках и названии оператора.
Это разница в названии операторов и синтаксисе. Это мелочь, поймите — концептуальная разница где-то меньше между П и Ф, где-то между П и Б. Но практически везде велика между Ф и Б.
Я все же напишу примеры как-нибудь, надо настроить среды для Ф и Б.
Мне не совсем понятня механика в данном случае: насколько я понимаю STL, .end() — особый вид итератора, который невалиден и располагается за последним элементом. Мы предполагаем здесь, что при двойной инкрементации мы можем попасть в зацикливание. Что происходит при инкрементации итератора .end()?
—
Ага, ну тогда ясно. Непонятно, почему не сделать так, что инкремент .end()'а давал бы тот же .end().
Есть ли технически разница с it != v.end()?
Что-что?
Кто мешает сделать
Нет, не только. Это стандартное объявление в самых разных ЯП аж с Фортрана: начало, конец и приращение.
Нет, это ты сам одолжил у себя в другом времени. У себя завтрашнего, например. Ценность знаний, так же, как и денег, зависит от времени.
Человек постоянно исполняет множество социальных ролей, здесь нет никакого болезненного раздвоения. И да, одна социальная роль может одолжить у другой; не буквально, а в рамках модели. Ты вчера и ты сегодня — это разные люди.
Это означает, что вы слово «долг» понимаете иначе, чем автор статьи. Только и всего. Для автора, судя по всему, (и для меня) «взять в долг у себя завтрашнего» — вполне нормальная фраза.
Я сказал, что ваш аргумент фактически сводится к этому.
Вы под новичком, видимо, имеете в виду начинающего профессионального разработчика, я — изучающего язык. Тот, кто «уже не студент», тем более будет знать обсуждаемую особенность. Я думал, мы говорим о начинающих.
Хоспаде, очевидно же, что речь не про «с нулевыми в абсолютном выражении накладными расходами».
датьсохранить ссылку на страницу — это не стандарт.У вас есть функция, которая связывает яркость пикселя с символом. Не блок пикселей (что могло бы определить форму), а яркость.
Это уже не очень хорошее начало. Потому что виртуальный деструктор, о котором мы говорим, нам понадобится, если мы собираемся удалять объект по ссылке на его родительский тип, т.е. например если мы заносим его в коллекцию, которая контроллирует время жизни объекта. Например, это какие-то control'ы (виджеты, итп) и нам надо их занести в список «контролы окна», по которому мы будем потом проходить и в случае «чего» удалять их безотносительно внутренней реализации. Это уже не для новчика.
Странно; все книжки по «плюсам», которые я читал, всегда оговаривают последовательность вызова деструкторов, из которой ясно, как оно будет работать при вызове деструктора родительского класса.
Это, конечно, может быть проблемой — я, пожалуй, спишу на субъективность, как и то, что С++ — не мой основной язык, и не первый ООП язык для меня. Мне кажется, что достаточно понимать последовательность вызова д-в и придерживаться простого правила — не уверен, сделай д. вирутальным. Ресурсов это не сожрет.