C++
char const * a;
D
const(char)* a;
immutable(char)* a;
В обоих случаях мы можем изменять значение самого указателя (менять адрес, который он хранит), но не можем менять данные по этому адресу.
Тут код будет проще на D:
C++
char const * const a;
D
const(char*) a;
immutable(char*) a;
Здесь мы уже не можем изменить ни указатель не данные по адресу.
Вот тут возникает проблема с D: средствами языка это не реализуется. Но можно сделать это через принудительный обход системы типов. Такой подход категорически не рекомендуется и, возможно, создаёт ситуации для udefined behavior. В большинстве случаев, когда нужно быть уверенным, что поле нельзя будет перезаписать другим объектом, но объект нужно менять можно использовать приватные поля/переменные, возвращаемые методами/функциями.
C++
char * const a;
D
(проверенно на linux dmd-2.078.0)
import std.stdio;
const struct Imm(T)
{
private T _data; // const транзитивно распостраняется на поля
alias data this;
// Реализация обхода системы типов через приведение указателей
ref T data() const { return *(cast(T*)&_data); }
}
void main()
{
auto a = Imm!(char[])(new char[](10));
// typeof(a) == const Imm!(char[])
//a = "hello"; // присвоить нельзя
a[] = "helloworld"; // заполнить значениями можно
writeln(a);
auto b = Imm!(char[])(new char[](2));
b[0..2] = "ab";
b.length = 10;
b[2..5] = "cde";
writeln(b);
//a = b; // нельзя
}