Рассмотрим следующий код. Я предполагал, что, указав тип строго типизированного перечисления, я смогу использовать его для передачи функций и шаблонов одного типа, поскольку указанный базовый тип один и тот же; хотя компилятор жалуется, что приведение к типу отсутствует. В приведенном ниже коде удаление ключевого слова class
и спецификатор на перечислении Test::TOTAL_ITEMS
вернуться к TOTAL_ITEMS
буду работать. Я понимаю, что они не хотят никаких преобразований типов для строго типизированных перечислений, но когда базовый тип совпадает с типом, который, как ожидается, будет получен функцией или шаблоном, я ожидаю, что компилятор не будет жаловаться на это и не будет принудительно конкретный актерский состав. Мысли?
#include <iostream>
#include <cstdint>
template <typename T, std::size_t N = 10>
class Y {
public:
Y() : z_() {
}
~Y() = default;
private:
T z_[N];
};
class X {
public:
enum class Test : std::size_t {
ITEM1 = 0,
ITEM2,
TOTAL_ITEMS,
};
private:
Y<int, Test::TOTAL_ITEMS> collection;
};
int main() {
X xx;
}
Вся цель перечислений в области видимости заключается в предотвращении неявных преобразований в базовый тип. Вам нужно будет привести его, чтобы ваш код компилировался
#include <type_traits>
Y<int, static_cast<std::underlying_type<Test>::type>(Test::TOTAL_ITEMS)> collection;
Или, если все, что вас волнует, это указание базового типа для вашего перечисления, тогда отбросьте class
ключевое слово из его определения, и ваш код будет скомпилирован как есть.
enum Test : std::size_t {
// ...
};
Цель enum class
это чтобы его экземпляры неявно приводились к другому типу. Вот почему удаление class
компилирует: обычный enum
экземпляры неявно приводят к тому, что может их базовый тип
Когда вы хотите конвертировать enum class
к другому типу, вы должны сделать это эксплицитно:
enum class Foo : int { FEE, FYE, FOE, FUM };
void f(Foo x) {};
void g(int x) {};
int main()
{
f(Foo::FEE); // Okay: correct type
//f(0); // Error: no implicit conversion
f(static_cast<Foo>(0)); // Okay: explicitly converted
//g(Foo::FYE); // Error: no implicit conversion
g(1); // Okay: correct type
g(static_cast<int>(Foo::FYE)); // Okay: explicitly converted
}
Живая демо. Увидеть std::underlying_type
когда вы хотите программно извлечь тип.