В С++ 11 введены строго типизированные перечисления с синтаксисом enum class
. Они несовместимы с целыми типами и требуют явного приведения для получения их числового значения. С++ 11 также вводит возможность указать класс хранения для слабо типизированных перечислений с формой enum name : type {}
. Здесь все хорошо.
Но похоже, что даже если слабо типизированное перечисление имеет заданный класс хранения, тип его элементов по-прежнему int
. Я попытался с выпуском Visual Studio 2012, ноябрь CTP. Рассмотрим следующий код:
enum charEnum : char { A = 'A' };
enum longEnum : long long { Tera = 1000000000000 };
void fct(char val) {}
void fct(int val) {}
void fct(long long val) {}
int main()
{
static_assert(sizeof(A) == sizeof(char), "check charEnum size");
static_assert(sizeof(Tera) == sizeof(long long), "check longEnum size");
fct('A'); // calls fct(char)
fct(1); // calls fct(int)
fct(2ll); // calls fct(long long)
fct(A); // calls fct(int) !
fct(Tera); // calls fct(int), with truncation !
fct((long long)Tera); // calls fct(long long)
return 0;
}
Перегруженная функция, называемая значением перечисления, всегда fct(int)
, даже если это приводит к усечению значения. Конечно, при явном приведении мы можем вызвать перегруженную функцию, но это также возможно в традиционном синтаксисе С++ 03.
Я пропустил что-то очевидное? Почему это? Есть ли лучшее обходное решение, чем явный листинг?