Использование const_cast в C ++ вместо приведения в стиле C - PullRequest
7 голосов
/ 16 декабря 2008

Почему следующее?:

  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

Ответы [ 3 ]

20 голосов
/ 16 декабря 2008
  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 , вы также можете написать в него, что затем приводит к неопределенному поведению)

5 голосов
/ 16 декабря 2008

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

  • Pointers
  • Ссылки
  • Член-указатели

Поскольку ваши типы не являются ни одним из них, они не допускаются.

С другой стороны, приведенные вами примеры не тоже нуждаются const_cast.

0 голосов
/ 16 декабря 2008

за первую ошибку. const_cast может использоваться только для указателей или ссылочных типов. «int» не является ни тем, ни другим. Это может быть или не быть стандартом C ++ (не удалось найти хорошую ссылку). Но это относится к определенным реализациям, таким как компилятор MS C ++.

Для второй ошибки. const_cast может использоваться только для удаления const или volatile-квалификатора, но не для его добавления.

Ссылка: http://msdn.microsoft.com/en-us/library/bz6at95h(VS.80).aspx

...