просто по тому, что так ПОСТАНОВИЛИ
Именно так. Создатель языка взял идею из Алгола и урезал по субъективным причинам.
Исправление могло выглядеть как "let reference = new_object;"
Во-первых: я явно привел пример когда видно, что внутренняя реализация ссылок и указателей может быть различна - в случае gcc у них разные UB в случае const_cast'a.
Во-вторых: аргументы влада.
В-третьих: ссылка гарантирует что переменная валидна. Никаких нулей.
Алексей, смотрите. Использование указателя может транслироваться в:
1) Ничего. Оптимизация при известном адресе значения.
2) Копию
константного объекта в виде временной переменной.
3) В полях структур, в сложных выражениях, в результатах невстроенныхфункций — в указатель.
А если проще: без указателей реализовать поддержку ссылок нельзя. Без оптимизаций, сугубо на указателях можно. С этим-то все согласны?
Если разрешить переустанавливать ссылки, то 3-й пункт будет использоваться чуток чаще. При чём анализ потока управления происходит и сейчас. При совершении прыжка назад (goto) ссылка изменяется, а следовательно компилятор ничего не оптимизирует и в лоб выделяет место под неё.
Для гарантии не-NULL нужны проверки времени исполнения, иначе это не гарантии.
Я не очень понимаю различие между реализацией и, гм, оптимизацией реализации :-)
Оптимизация в стандарте не прописана, исходите из предположения её полного отсутствия.
В принципе полагаю возможно как минимум часть семантики (если не всю семантику) ссылок реализовать через простое копирование объекта (без вызовов конструкторов, тупо memcpy). И это не будет противоречить стандарту.
В лоб нельзя. Просто пара причин даже для этого ограниченного случая: goto разрешён (нужно проверять, устанавливается ли ссылка один раз), структурам и стековым кадрам нельзя жиреть (не будете же вы копировать по 5 КБ на объект), объявление указателей/ссылок возможно до полного определения структур. Поправьте, если где ошибаюсь.
Эмм.. Что за домыслы? Иммутабельность естественно имеет смысл в императивных языках. Функциональность довольно таки ортогональна иммутабельности :-) Впрочем, задам ка я вопрос - какое основное отличие функционального языка от императивного? Вот прям основное-основное.
Исправляюсь. Императивным языкам не свойственна навязанная неизменность. То есть дело не в том, чтобы объявлять саму ссылку const или нет, а в том, что она всегда константная. Возьмите указатели и примените к ним то же решение: указатели всегда константные. Что такое решение даёт программисту?
Э? При чем тут реализация?
MemoryFS mem_fs;
FileFS file_fs;
AnyFS &fs = file_fs;
...
if (some condition) let fs = file_fs; // такой "фичи" нет
Кто сказал что псевдонимы могут быть только детерминированными? :-)
Для меня есть два понятия: указатель на динамическую величину или псевдоним статической. То есть в случае псевдонима мы ещё на этапе компиляции знаем, к чему привязываемся. Но это субъективное восприятие, на дискуссии не настаиваю, да и ценность этого восприятия мала.
Покажи пожалуйста, ну, например на примере java, как ты собираешься бороться с нулями в изменяемых ссылках. То есть чтобы гарантированно, и не зависило от кривости рук программера.
Ну, например на том же примере твоем: vector<int> &a = rand() % 100 >= 50 ? b : c;
Пусть тут будет: 1) if..else. 2) не будет лишних инициализаций.
А мы не отменяем необходимость инициализации при объявлении.
Object &a = b;
...
let a = c;
...
let a = d;
где let — установка указателя, а не изменение значения объекта, на которого ссылаются.
Нет, итератеры не сделаны через указатели :-) И пусть тебя не смущает разименовывание и стрелочки для доступа к потрохам - это обычные объекты :-) Каждый указатель можно трактовать как итератор, но не каждый этератор является указателем. Вообще, с точки зрения С++, указатели - это такие кривые и недоделанные, кастрированные, итераторы.
Да, речь идёт о контейнерах со сплошным хранением элементов. И здесь я имел в виду физическую реализацию, когда итератор является структурой, содержащей один указатель и нет проверок времени исполнения на выходы за границы контейнера.
Не редко вижу в ответах фразы "In fact, vectors iterators are usually implemented as pointers.", но не проверял итераторы в исходниках STL. Хотя более чем уверен, либо просто указатель, либо структура из одного поля с набором требуемых inline-операторов.
А то что ты описал - не будет NULL-ссылкой. Будет UB чистой воды (причем по двум разным причинам одновременно). И нет, это не корректный код. :-)
Неопределённое поведение в стандарте не равно неопределённому поведению в реальности. В моей реальности программисты ошибаются, программы не идеальны, а некорректные ссылки не рушат программы до попытки обращения к объектам.
Ненулевость ссылок чисто декларативное свойство, а не средство отладки. Представь, что ты написал библиотеку с паблик функцией:
Согласен. Но я ни разу не предлагал разрешить ссылкам быть нулевыми. Я предлагал вернуть им возможность указывать на разные существующие объекты.
end() вообще нельзя разименовывать (по стандарту), это раз. Его разименовывание это UB.
Знаю. Но поскольку «нельзя» относится к тем же нельзя, что и «нельзя писать несовершенный код», то в реальности где-то будет опущена проверка результата.
то элемент следующий за последним явно будет иметь не нулевой адрес, не nullptr совсем.
begin() + size() он будет. begin() вернёт nullptr, а size() будет 0.
Три - чтобы запустить find на "пустой коллекции" нужно получить вначале начальный и конечный
итератор.
Ну да, будет возвращён end(), который есть nullptr.