Ошибка reinterpret_cast для перечисления

Почему я не могу использовать оператор reinterpret_cast для такого трансляции?

enum Foo { bar, baz };

void foo(Foo)
{
}

int main()
{
   // foo(0); // error: invalid conversion from 'int' to 'Foo'
   // foo(reinterpret_cast<Foo>(0)); // error: invalid cast from type 'int' to type 'Foo'
   foo(static_cast<Foo>(0)); 
   foo((Foo)0);
}

Ответ 1

Я думаю, что reinterpret_cast может использоваться для всех типов трансляций, потому что он принуждает любые типы приведения к другому типу со всеми побочными эффектами этого преобразования.

Это распространенное заблуждение. Конверсии, которые могут быть выполнены с помощью reinterpret_cast, явно указаны в 5.2.10 стандарта. int -to- enum и enum -to- int преобразований нет в списке:

  • Указатель на целочисленный тип, если целое число достаточно велико, чтобы удерживать его
  • nullptr_t в целое число
  • интегральный тип или enum для указателя
  • указатель функции к другому указателю функции другого типа
  • указатель объекта на другой указатель объекта другого типа
  • nullptr_t к другому типу указателя
  • указатель на элемент T1 на другой указатель на элемент T2 в случаях, когда оба T1 и T2 являются объектами или функциями

reinterpret_cast обычно используется, чтобы сообщить компилятору: Эй, я знаю, вы думаете, что этот регион памяти является T, но я бы хотел, чтобы вы интерпретировали его как U (где T и U являются несвязанными типами).

Также стоит отметить, что reinterpret_cast может влиять на бит:

5.2.10.3

[Примечание. Отображение, выполняемое reinterpret_cast, может или, возможно, не приведет к представлению, от исходного значения. - конечная нота]

Листинг C-style всегда работает, потому что он включил static_cast в свои попытки.

Ответ 2

Поскольку обычный тип перечисления, указанный ниже, int, нет reinterpret. Статический литой является правильное преобразование для этого случая.