2016-10-01 12 views
16

Czy istnieje sposób zapewnienia, że ​​parametr szablonu jest typem klasy wyliczeniowej?Upewnij się, że parametr szablonu jest klasą wyliczeniową

Wiem, że type_traits ma type_traits ma , ale nie chcę, aby dopasować regularne wyliczenia, tylko enum_classes.

Przykład efektu Poszukiwany

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 

Używam C++ 11, i niestety nie może iść wyżej (choć byłbym ciekaw rozwiązania w każdym razie, nawet jeśli wiąże się to nowe standardy).

Czy to możliwe?

Odpowiedz

17

Można to osiągnąć z:

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

Here demo.


Jeśli wolisz korzystać SFINAE, to samo można osiągnąć:

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

Popraw mnie jeśli się mylę, ale jesteś po prostu w zależności od faktu, że klasy enum nie są niejawnie zamienny do całek? Czy nie jest możliwe zdefiniowanie niejawnego operatora konwersji? –

+1

@GiladNaaman jak definiujesz niejawny operator z 'klasy enum'? –

+0

Tak, mój zły, nie możesz faktycznie zdefiniować operatorów lub funkcji wewnątrz "klasy enum". –

Powiązane problemy