Убедитесь, что параметр шаблона - это класс перечисления

Есть ли способ гарантировать, что параметр шаблона является типом класса enum?

Я знаю, что type_traits имеет std::is_enum, но я не хочу, чтобы он соответствовал регулярным перечислениям, просто enum_classes.

Пример желаемого эффекта:

enum class EnumClass {};
enum Enum {};
class Class {};

template <typename T>
void Example()
{
    static_assert(/* T is EnumClass */, "`T` must be an enum class");
}

Example<EnumClass>(); // Ok
Example<Enum>(); // Error
Example<Class>(); // Error

Я использую С++ 11 и, к сожалению, не могу подняться выше (хотя мне было бы интересно узнать решение в любом случае, даже если оно связано с более новыми стандартами).

Возможно ли это?

Ответы

Ответ 1

Вы можете добиться этого с помощью:

template<typename T>
using is_class_enum = std::integral_constant<
   bool,
   std::is_enum<T>::value && !std::is_convertible<T, int>::value>;

Здесь демо.


Если вы предпочитаете использовать SFINAE, то это может быть достигнуто с помощью:

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

template<typename T>
struct is_class_enum <
  T,
  typename std::enable_if<std::is_enum<T>::value &&
                          !std::is_convertible<T, int>::value>::type> :
    public std::true_type {
};