История изменений
Исправление byko3y, (текущая версия) :
Это не проблема const, а проблема shared_ptr, который в константном операторе «*» возвращает _не_ константную ссылку. Он по поведению пытается прикидываться сырым указателей. const shared_ptr<T> это T * const, а не const T *. Если такие фокусы не вытворять, то const нормально пробрасывается и блокирует попытки изменений, как в моём примере
Авторы STL постарались максимально обтекать вокруг кривизны const. На самом деле есть кучу потенциальных задач, где понадобится менять поля объекта с «константным» значением — об этом я писал изначально. Авторы STL до последнего пытались делать вид, что проблемы не существует, но shared_ptr оказался слишком лакомым кусочком, чтобы избегать его реализации, а на него const не налазит, криво получается хоть так, хоть эдак. Он не является исключением, это самый обычный контейнер, довольно примитивный, но он прекрасно демонстрирует убогость крестового const, который тут работает, а здесь уже не работает.
Напоминаю, что мой главный аргумент был в том, что const работает «через раз». Если довести это до абсурда, то можно сказать «в языкнейме ссылки безопасные, они иногда дают гарантии корректной работы с памятью, а иногда — не дают. Но если постараться, то можно сделать так, что чаще будут давать гарантии, чем не давать» — это что за такие «гарантии»? Если по итогу ошибки логики с недопустимым изменением переменной я все равно буду отслеживать руками, то в чем ценность этой гарантии? Это коммент. Кому-то полезный, кому-то удобный. Но можно писать совсем без него, пользуясь другими комментами, другими псевдонимами типов. А можно и с ним. Но мне нравится без него. STL написан с const — при использовании STL придется использовать const. Но если я не пишу на STL, то я могу обойтись без const.
Исходная версия byko3y, :
Это не проблема const, а проблема shared_ptr, который в константном операторе «*» возвращает _не_ константную ссылку. Он по поведению пытается прикидываться сырым указателей. const shared_ptr<T> это T * const, а не const T *. Если такие фокусы не вытворять, то const нормально пробрасывается и блокирует попытки изменений, как в моём примере.