Давайте разберем это, используя константный синтаксис EAST.
Правило const состоит в том, что оно всегда применяется к тому, что находится слева от него, если только от него ничего нет, в этом случае оно применяется к тому, что находится непосредственно справа. С EAST const мы всегда пишем const справа.
Итак, давайте посмотрим на код:
const char* const& a = "bla"; // Valid code
становится
char const * const & a = "bla";
так что символ постоянен и не может быть изменен.
Указатель на символ постоянен и не может быть изменен.
В целом: это ссылка на указатель, который нельзя изменить на символ, который нельзя изменить.
"bla" - это массив const C-style, который сразу распадается на char const * const.
Причина, по которой он является «char const * const», а не «char const *», заключается в том, что адрес «bla» является постоянным - строка «bla» компилируется в код выполнения где-то в фиксированном месте, и когда загруженный в память будет оставаться на этом адресе памяти до завершения программы.
Так что теперь у нас есть подходящие типы, кроме ссылки.
T & a = что-то; всегда будет работать, если что-то имеет тип T, а у чего-то есть адрес (это так).
Давайте посмотрим на второй:
const char*& a2 = "bla";
Синтаксис EAST const:
char const * & a2 = "bla";
«бла» относится к типу:
char const * const
Это не совпадающие типы (место памяти "bla" фиксировано).
Может быть, этот код сделает его более понятным:
char const *stringPtr = "hello";
char const *stringPtr2 = "world";
char const * &stringPtrRef = stringPtr;
std::cout << stringPtr << std::endl;
stringPtrRef = stringPtr2;
std::cout << stringPtr << std::endl;
Будет напечатано «Hello» в первой строке и «World» во второй. Это потому, что stringPtr указывает на изменения.
Поскольку местоположение «bla» является фиксированным, мы не можем создать ссылку на него, где местоположение «bla» можно изменить, установив ссылку на него на что-то другое. Это просто невозможно. Нет также никакого возможного броска, который мы могли бы использовать, чтобы заставить его стать правильным типом.
Вот почему он не может компилироваться даже с предупреждениями.
Давайте посмотрим на третий:
char* const& a3 = "bla";
Это уже в формате EAST const.
с "char * const &" - результирующая ссылка, не позволяя изменить расположение в памяти, позволит вам изменить "bla" на "abc".
Возможно, в некоторых случаях вы действительно хотите сделать это, чтобы сэкономить пространство памяти в некоторых встроенных системах, где «bla» использовался только в качестве инициализации и никогда больше.
Сообщение имеет смысл:
"предупреждение: ISO C ++ запрещает преобразование строковой константы в 'char *"
потому что это по сути то же самое, что и
char const *s1 = "bla";
char *s2 = s1;
, который фактически скомпилируется с предупреждением с правильными флагами компилятора (-fpermissive).
Даже без -fpermissive мы могли бы изменить код, чтобы выполнить приведение и заставить его работать.
Итак, я понимаю, почему он может компилироваться, но я думаю, что это должно быть ошибкой. ISO C ++ явно запрещает это. Мое мнение: Требуй актерский состав, если это действительно то, что ты хочешь сделать.