отбрасывание константы с помощью const_cast

Нет. Этот вопрос не дубликат
Когда следует использовать static_cast, dynamic_cast, const_cast и reinterpret_cast?

Заданный здесь вопрос не похож на ссылку, описанную как дубликат.

Первый вопрос :
Я использую const_cast ниже для двух случаев. один из них работает. другой нет.

1. int * const //Работает.

В этом синтаксисе адрес, на который будет указывать переменная, не может быть изменен. Поэтому я использовал const_cast, как показано ниже, и он работает:

`
int j=3;
int *k=&j;
int *m=&j;
int* const i=k;
const_cast<int*>(i)=m; //OK: since i=m would not work so cast is necessary`

2. const int * // Не работает.

Указанный адрес может быть изменен, однако значение не может быть изменено (хотя его можно изменить, указав переменную, указывающую на другой адрес). Const_cast, который я использую, похоже, не работает здесь:

`
int j=9;
int *k=&j;
const int* i1=0;
i1=k; //OK
//*i1=10;//ERROR.`

Поэтому я попытался выполнить приведенную ниже последовательность действий различными способами, но ничего не работает:

const_cast<int*>(i1)=10;
const_cast<int*>(*i1)=l;
*i1=const_cast<int>(l);
*i1=const_cast<int*>(10);

Второй вопрос:
Все ли броски доступны только для указателей и ссылок?
Разве следующий пример недопустим, если на картинке нет указателя или ссылки?

const int a=9;
int b=4;
const_cast<int>(a)=b; //cannot convert from 'int' to 'int'. why is compiler
//trying to convert from int to int anyways or fails
//when both the types are same.

2

Решение

const_cast применяется к выражения, не объекты, а сам по себе является выражение также:

§ 5.2.11 [expr.const.cast] / p1:

Результат выражения const_cast<T>(v) имеет тип T, Если T является lvalue ссылкой на тип объекта,
результат — lvalue; если T является rvalue ссылкой на тип объекта, результат — xvalue; в противном случае результат
является prvalue и стандартом lvalue-to-rvalue (4.1), массивом-указателем (4.2) и функцией-указателем (4.3)
преобразования выполняются по выражению v

  1. const_cast<int*>(i)=m;

Этот вызов недействителен, потому что левая сторона назначения имеет prvalue категория стоимости и int* prvalue не поддерживает назначение. Правильный синтаксис будет const_cast<int*&>(i)=m;, но с тех пор i в вашем примере было объявлено const, это будет вызывать неопределенное поведение .

  1. const_cast<int*>(*i1)=l;

Разыменование указателя типа int* создает выражение для значения-категории lvalue, и поскольку выражение приведения находится в левой части присваивания, оно должно быть приведено к ссылочному типу lvalue, а именно const_cast<int&>(*i1)=10; (при условии, что все i1 указывает на не было объявлено const).

  1. const_cast<int>(a)=b;

const_cast<int>(a) сама часть является допустимой, в частности, вы можете применить const_cast к выражению, представляющему объект, который не относится к типу указателя и не является ссылочным типом. Но так как он находится на левой стороне задания, он не скомпилируется. И даже если вы измените его на const_cast<int&>(a)=b; это вызовет неопределенное поведение, потому что a объявлен const .


§ 7.1.6.1 [dcl.type.cv] / p4:

За исключением того, что любой член класса, объявленный mutable (7.1.1), может быть изменен, любая попытка изменить const
объект в течение его жизни (3.8) приводит к неопределенному поведению.

3

Другие решения

Первый ответ: В вашем примере вы пытаетесь заставить компилятор сделать что-то, что можно интерпретировать следующим образом

const_cast<int*>(i1)=10; //int* = int: assign address to pointer
const_cast<int*>(*i1)=l; //const_cast<int*>(int): cast the value under pointer to pointer
*i1=const_cast<int>(l); //const_casting from const values is forbidden
*i1=const_cast<int*>(10); //10 is an rvalue

Здесь вы действительно хотите разыменовать указатель, который больше не является константным. Вот почему вам нужно сделать это так:

int j = 9;
int *k = &j;
const int* i1 = 0;
i1 = k;
*(const_cast<int*>(i1)) = 10;

что эквивалентно

int j = 9;
int *k = &j;
const int* i1 = 0;
i1 = k;
int* temp = const_cast<int*>(i1); //you get rid of 'const'...
*temp = 10; //...and now you assign value as you wanted to - this operation became available

Второй ответ: Запрещено const_cast константные значения, поскольку это приводит к неопределенному поведению. Вам разрешено удалять только константы из указателей или ссылок, которые указывают на то, что на самом деле не const в конце и только указатель не позволяет вам изменить его значение.

Эта проблема прекрасно описана в этот ответ.

2