Введите trait для значения элемента enum - PullRequest
1 голос
/ 12 марта 2020

У меня есть черта типа, чтобы проверить, содержит ли enum class элемент с именем None.

template<typename T, typename = void>
    struct has_none : std::false_type
    {
    };

template<typename T>
struct has_none<T,
    std::void_t<decltype(T::None)>> : std::true_type {};

Эта проверка будет связана с std::is_enum_v. Вопрос в том, как мне создать type_trait, который бы проверял, что Enum::None имеет значение 0? Возможно ли вообще говорить о type_traits?

Ответы [ 2 ]

5 голосов
/ 12 марта 2020

Использование std::enable_if:

template <typename T, typename = void>
struct has_none : std::false_type {};

template <typename T>
struct has_none<T, std::enable_if_t<T::None == T(0)>> : std::true_type {};
2 голосов
/ 12 марта 2020

Вы можете использовать conditional_t, чтобы выбрать true_type / false_type в качестве базового класса в зависимости от того, истинно условие или нет:

template<class E>
constexpr auto EnumToInt(E e) {
    return static_cast<std::underlying_type_t<E>>(e);
}
enum class Foo {
    None = 0
};
enum class Bar {
    None = 1
};
template<class T>
struct NoneAs0 : std::conditional_t< EnumToInt(T::None) == 0,
    std::true_type, std::false_type>
{};

int main() {
    std::cout << NoneAs0<Foo>::value << std::endl; // 1
    std::cout << NoneAs0<Bar>::value << std::endl; // 0
...