【问题标题】:Template specialization for enum枚举的模板特化
【发布时间】:2010-12-09 20:26:12
【问题描述】:

是否可以为枚举专门化模板化方法?

类似(下面的无效代码):

template <typename T>
void f(T value);

template <>
void f<enum T>(T value);

如果不可能,那么假设我有多种类型的特化,例如intunsigned intlong longunsigned long long 等,那么枚举值将使用哪些特化?

【问题讨论】:

标签: c++ templates enums template-specialization


【解决方案1】:

您可以使用 std::enable_if 和来自 &lt;type_traits&gt;std::is_enum 来完成此操作。

In an answer to one of my questions, litb 发布了一篇非常详细且写得很好的解释,说明如何使用 Boost 等效项完成此操作。

【讨论】:

  • 这看起来可能有效。我正在看它。谢谢!
【解决方案2】:

我不确定我是否正确理解了您的问题,但您可以在特定枚举上实例化模板:

template <typename T>
void f(T value);

enum cars { ford, volvo, saab, subaru, toyota };
enum colors { red, black, green, blue };

template <>
void f<cars>(cars) { }

template <>
void f<colors>(colors) { }

int main() {
    f(ford);
    f(red);
}

【讨论】:

  • 那行不通,因为我事先没有枚举类型。
  • 在 C++11 中你有类型,因此你可以创建枚举模板。一个更好的主题是根据枚举的特定值(f)创建一个模板。仍然可以使用一些技巧,或者可以通过声明类而不是枚举值来避免。
【解决方案3】:

大概,你可以对一个类型做的唯一有趣的事情是,你只知道它是一个枚举,将它转换为它的底层类型并对其进行操作。以下是使用 James 建议的方法 (AKA SFINAE) 的样子:

void Bar(int b); // and/or other underlying types

template<typename T>
typename std::enable_if<std::is_enum<T>::value, void>::type
Foo(T enm)
{
    Bar(static_cast<typename std::underlying_type<T>::type>(enm));
}

作为一个相关的奖励,这里有一个类似的方法,只能解决您选择的特定类型(将 is_same 中的 bool 替换为您选择的类型):

template<typename T>
typename std::enable_if<std::is_same<T,bool>::value, void>::type
Baz(T bl)
{
    if (bl)
    {
        //...
    }
    else
    {
        //...
    }
}

【讨论】:

    【解决方案4】:

    您也可以在模板参数之一中使用std::enable_if。 如果无法编译,则根本不实例化该函数(SFINAE)。

    template <typename T>
    void f(T value) 
    { /* implementation A */ }
    
    template <typename T,
              typename = std::enable_if<std::is_enum<T>::value, bool>::type >
    void f(T value) 
    { /* implementation B */ }
    

    我提出上述解决方案作为对那些建议您使用std::enable_if 作为函数的返回类型的补充。在您的问题中,您不希望更改返回类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 2023-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多