const int i0 = 5;
//int i1 = const_cast<int>(i0); // compilation error
int i2 = (int)i0; // okay
int i3 = 5;
//const int i4 = const_cast<const int>(i3); // compilation error
const int i5 = (const int)i3; // okay
Ошибки компиляции вызваны тем, что вы не отбрасываете const и не добавляете const. Вместо этого вы копируете i0. Для этой операции никакое приведение не требуется вообще:
int i1 = i0;
const int i4 = i3;
Тип, который вы приводите, должен быть указателем или ссылкой. В противном случае использование const_cast не имеет смысла, поскольку вы можете скопировать его прямо. Например, для указателей вы можете отказаться от const, потому что разыменование указателя даст другой тип для const T*
(выход const T
), чем для T*
(выход T
). Для ссылок то же самое верно: T&
получит доступ к объекту, используя другой этот тип указателя, чем const T&
. Теперь то, что вы действительно хотели заархивировать:
const int i0 = 5;
//int & i1 = const_cast<int&>(i0); // okay (but dangerous)
int & i2 = (int&)i0; // okay (but dangerous)
int i3 = 5;
//const int&i4 = const_cast<const int&>(i3); // ok now and valid!
const int&i5 = (const int&)i3; // okay too!
Вышеприведенное может привести к неопределенному поведению, когда вы пишете в изначально const-объект посредством ссылки на неконстантное (на самом деле, просто приведение и чтение его не является неопределенным поведением само по себе. Но если вы отбрасываете const , вы также можете написать в него, что затем приводит к неопределенному поведению)