Я думаю, что было бы целесообразно опубликовать основные выводы недавней ветки по этой теме в группе новостей D здесь, чтобы те, кто не отслеживает этот список, могли получить соответствующий ответ..
Const D не является логическим const.Это переходный и полностью постоянный.Язык технически не поддерживает логическое постоянство.Язык не определяет какой-либо способ мутировать объект const.
И на самом деле, C ++ также не имеет логического const.Использование mutable
и удаление константности позволяет вам полностью обойти const, так что с технической точки зрения const на самом деле ничего не гарантирует, за исключением того, что вы не вызываете неконстантные функции для переменной const.Тот факт, что константные функции на самом деле являются константными и не связаны с вашими переменными, полностью согласуется.Теперь большинство программистов не разбрасывают константу влево и вправо и делают все изменчивым, так что на практике это весьма полезно, но не только полностью обходится, но язык специально дает вам определенные средства для этого,В C ++ mutable
и отбрасывании const четко определены и поддерживаются языком.
D этого не делает.Констант Д на самом деле констант.Отбрасывание const для переменной и последующее ее изменение не определены.Там нет изменяемого.У const у D есть реальные гарантии (если вы не делаете ничего неопределенного, например, отбрасываете const на что-то и затем изменяете его).Это важно не только потому, что гарантии компилятора для D намного сильнее, чем гарантии для C ++, но и потому, что неизменяемые переменные не могут быть каким-либо образом изменены .Они могут находиться в памяти только для чтения, и кто знает, какие ужасные вещи произойдут, если вы попытаетесь отбросить неизменность и изменить такую переменную (segfault, вероятно, будет самой хорошей вещью, которая может произойти).А поскольку переменная const может фактически ссылаться на неизменяемые данные, отбрасывание const для изменения переменной или предоставление возможности каким-либо образом изменить переменные const будет, по меньшей мере, плохим .Итак, язык не позволяет этого.
Теперь, как указывает BCS , D - прагматический язык.Вы можете отбрасывать const, после чего вы можете изменить переменную.Так, например, вы могли бы иметь переменную, которая использовалась для кеширования возвращаемого значения const-функции (предположительно, если этот кеш был признан недействительным, если состояние объекта изменилось), и отбрасывать const, чтобы изменить его.Пока рассматриваемая переменная не является на самом деле неизменной, она будет работать.Тем не менее, это поведение undefined .Как только вы это сделаете, вы сами по себе.Вы обходите систему типов и гарантии компилятора. Вы несете ответственность за то, чтобы убедиться, что вы не делаете это на неизменяемом объекте и не испортите то, что обычно гарантирует компилятор.Итак, если вам нужно , чтобы сделать это, вы можете, но вы выходите на Дикий Запад, и вы должны убедиться, что вы не мутируете, что не должны.
Учитывая, что отбрасывание const будет работать до тех пор, пока переменная на самом деле не ссылается на неизменяемые данные, можно создать шаблон Mutable
, чтобы по существу получить то, что mutable
дает вам в C ++ (так чтоэто сделает отбрасывание константы за вас). he_the_great приводит пример такого шаблона в своем ответе.Но использование такого шаблона до сих пор не определено.Использование его на объекте, который на самом деле неизменен, вызовет проблемы. Программист должен убедиться, что он используется правильно.
Итак, D делает технически возможным иметь логическое const, отбрасывая const, но для того, чтобы сделать это, вы должны выйти за пределы того, что компилятор гарантирует, обходя систему типов, и вы должны убедиться, что вы не используете не используйте его не по назначению и не изменяйте переменные, которые не должны / не могут быть изменены, иначе ваш код будет иметь проблемы - вполне возможно, что segfaults - наименьший среди них.
РЕДАКТИРОВАТЬ: Я забыл упомянуть одно предлагаемое решение, которое не нарушает систему типов. Пока вы готовы отказаться от чистоты, вы можете использовать глобальную переменную некоторого разнообразия (будь то в области видимости модуля, переменной класса или переменной структуры) для хранения ваших кэшированных значений. Функция const может свободно использовать и изменять глобальные переменные, поэтому ее можно использовать вместо отсутствующего mutable
. Это, однако, означает, что функция не может быть чистой, что также может быть большой проблемой. Это, однако, способ иметь функцию const, которая по-прежнему может изменять необходимые данные, не нарушая систему типов.