9

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

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

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

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

在不可能的情况下,假设我有多种类型的特化,比如int, unsigned int, long long,unsigned long long等,那么枚举值将使用哪些特化?

4

4 回答 4

22

您可以使用std::enable_ifwith std::is_enumfrom<type_traits>来完成此操作。

在回答我的一个问题时,litb 发布了一个非常详细且写得很好的解释,说明如何使用 Boost 等效项来完成此操作。

于 2009-10-25T04:31:56.220 回答
7

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

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);
}
于 2009-10-25T04:33:58.087 回答
2

据推测,你可以对一个类型做的唯一有趣的事情是你只知道它是一个枚举,将它转换为它的底层类型并对其进行操作。以下是使用 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));
}

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

template<typename T>
typename std::enable_if<std::is_same<T,bool>::value, void>::type
Baz(T bl)
{
    if (bl)
    {
        //...
    }
    else
    {
        //...
    }
}
于 2016-12-01T10:36:53.337 回答
0

您还可以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在函数中用作返回类型的解决方案的补充。在您的问题中,您不希望更改返回类型。

于 2021-01-05T17:04:47.963 回答