Gilad Naaman Gilad Naaman - 10 months ago 58
C++ Question

Ensure template parameter is an enum class

Is there a way to ensure a template parameter is an enum-class type?

I know

type_traits
has
std::is_enum
, but I don't want it to match regular enums, just enum_classes.

Example of the wanted effect:

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


I am using C++11, and unfortunately cannot go any higher (though I'd be curious to know the solution anyway, even if it involves newer standards).

Is it possible?

Answer Source

You can achieve it with:

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

Here a demo.


If you prefer using SFINAE, the same can be achieved with:

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 {
};