【问题标题】:How can I partially specialize a class template for enums values?如何部分专门化枚举值的类模板?
【发布时间】:2019-06-18 08:49:08
【问题描述】:

模板可以根据枚举值进行专门化

#include <type_traits>

template<typename T, typename = void>
struct Specialize
{
};

template<typename T>
struct Specialize<T, typename std::enable_if<std::is_enum<T>::value>::type>
{
    void convert() { }
};

enum E
{
};

int main()
{
    Specialize<E> spec;
    spec.convert();
}

// My doubt: is below code valid? if not how to achieve this?

enum E
{
    E1,
    E2
};

int main()
{
    Specialize<E, E1> spec;
    spec.convert();
}

这是对以下问题的回答的后续问题。

How can I partially specialize a class template for ALL enums?

我已经复制粘贴了上面链接问题答案中的代码。

我的更改出现以下错误。

error: type/value mismatch at argument 2 in template parameter list for _template<class T, class>

【问题讨论】:

    标签: c++ c++11 templates sfinae template-specialization


    【解决方案1】:

    // 我的疑问:下面的代码有效吗?

    Specialize&lt;E, E1&gt; spec;

    简短回答:不。

    长答案。

    您已将Specialized 定义为模板struct 接收两个类型 模板参数

    template<typename T, typename = void>
    struct Specialize
    {
    };
    

    E 是一个类型,但 E1 是一个

    如果不是怎么实现呢?

    如果您希望您的 struct/class 接收作为模板参数的类型和该类型的值,则启用 struct/class 的特化当且仅当type 是一个枚举,你必须添加typename = void 作为第三个模板参数

    template<typename T, T Val, typename = void>
    struct Specialize
    {
    };
    
    template<typename T, T Val>
    struct Specialize<T, Val, typename std::enable_if<std::is_enum<T>::value>::type>
    {
        void convert() { }
    };
    

    从 C++17 开始,您还可以使用 auto 作为模板值的类型并删除第一个模板参数

    template<auto Val, typename = void>
    struct Specialize
    {
    };
    
    template<auto Val>
    struct Specialize<Val, std::enable_if_t<std::is_enum_v<decltype(Val)>>>
    {
        void convert() { }
    };
    

    -- 编辑--

    OP 询问

    我们如何在结构/类之外定义函数“convert”?

    不幸的是,在这种情况下,我看不到避免 std::enable_if 重复的方法

    template <typename T, T Val>
    struct Specialize<T, Val,
       typename std::enable_if<std::is_enum<T>::value>::type>
     { void convert(); };
    
    template <typename T, T Val>
    void Specialize<T, Val,
       typename std::enable_if<std::is_enum<T>::value>::type>::convert ()
     { };
    

    【讨论】:

    • 我们如何在结构/类之外定义函数“convert”? Specialize::value>::type>::convert() { }
    • @VinKris - 答案改进;希望这会有所帮助。
    【解决方案2】:

    您的编译器告诉您Specialize&lt;E, E1&gt; spec; 无效。

    您可以使用std::integral_constant 将值包装在类型中。

    template<typename T, T V>
    struct Specialize<std::integral_constant<T, V>, typename std::enable_if<std::is_enum<T>::value>::type>
    {
        void convert() { }
    };
    
    int main()
    {
        Specialize<std::integral_constant<E, E1>> spec;
        spec.convert();
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-25
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-15
      • 1970-01-01
      相关资源
      最近更新 更多