如何为底层类型int的枚举专门化一个类?

时间:2018-04-11 11:39:55

标签: c++ c++11

#include <type_traits>

enum class MyEnum
{
    Hello
};

template <typename T, typename Enable = void>
class MyClass
{
public:
    MyClass(T obj) : e(obj)
    {}

private:
    T e;
};

template <typename T>
class MyClass <T, 
    typename std::enable_if< std::is_enum<T>::value 
                             && std::is_same<typename std::underlying_type<T>::type, 
                                             int>::value>::type > 
{
public:
    MyClass(T obj) : e(obj)
    {}

private:
    T e;
};

int main()
{
    MyClass<MyEnum> c(MyEnum::Hello);
    MyClass<int> c1(1); //does not compile due to std::underlying_type
    return 0;
}

我希望能够将MyClass专门用于底层类型'int'的枚举。我不能使用std :: underlying_type这样做,因为它只针对枚举。 关于如何进行的任何想法?

2 个答案:

答案 0 :(得分:10)

这个怪癖的一个简单的解决方案是将std::underlying_type隔离在你自己的SFINAE友好特征背后:

template <class T, class = void>
struct underlying_type {};

template <class T>
struct underlying_type<
    T,
    typename std::enable_if<std::is_enum<T>::value>::type
> {
    using type = typename std::underlying_type<T>::type;
};

然后你的专业化可以写成:

template <typename T>
class MyClass<
    T, 
    typename std::enable_if<std::is_same<
        typename underlying_type<T>::type,
        int
    >::value>::type
> {
    // ...
};

答案 1 :(得分:3)

使用conditional<..>::type::type进行一次额外(延迟)间接:

template <typename T> struct Identity { using type = T; };

template <typename E>
class MyClass <E, 
    typename std::enable_if<
        std::is_enum<E>::value 
        && std::is_same<
            int,
            typename std::conditional<
                std::is_enum<E>::value,
                std::underlying_type<E>,
                Identity<E>
            >::type::type
        >::value
    >::type
>
{
    // ...
};

我们确实只为枚举std::underlying_type<E>::type

Demo