其他分享
首页 > 其他分享> > C专门针对枚举功能

C专门针对枚举功能

作者:互联网

是否可以在枚举上专门化模板函数?

我已经注意到here模板功能可以被禁用,如果它不是枚举,但这是否可能,同时仍然允许其他类型?

我的示例显示了int,float和enum的特殊化(它不会编译,因为它会尝试重载枚举版本而不是专门化它).我觉得我错过了一些明显的东西.

请注意,我希望专注于任何枚举,而不仅仅是命名的枚举(示例中为EAnEnum)

#include <iostream>

enum class EAnEnum
{
    Alpha,
    Beta,
};

template<typename T>
void MyFunc();

template<>
void MyFunc<int>()
{
    std::cout << "Int" << std::endl;
}

template<>
void MyFunc<float>()
{
    std::cout << "Float" << std::endl;
}

// MyFunc<Enum>
template<typename T>
typename std::enable_if<std::is_enum<T>::value, void>::type MyFunc()
{
    std::cout << "Enum" << std::endl;
}

int main()
{
    MyFunc<EAnEnum>();
    return 0;
}

解决方法:

您不能部分专门化函数,但可以使用标记调度.
它遵循一个基于OP问题的最小的工作示例:

#include <iostream>
#include<type_traits>

enum class EAnEnum
{
    Alpha,
    Beta,
};

template<typename>
struct tag {};

void MyFunc(tag<int>)
{
    std::cout << "Int" << std::endl;
}

void MyFunc(tag<float>)
{
    std::cout << "Float" << std::endl;
}

void MyFunc(tag<EAnEnum>)
{
    std::cout << "Enum" << std::endl;
}

template<typename T>
void MyFunc() {
    MyFunc(tag<std::decay_t<T>>{});
}

int main()
{
    MyFunc<EAnEnum>();
    return 0;
}

您可以轻松添加要转发到右侧MyFunc的参数包,并仍然使用此技术来解决您的问题.
当然,你现在可以专注于任何枚举.
您还可以提供后备MyFunc:

template<typename T>
void MyFunc(tag<T>)
{
    std::cout << "Fallback" << std::endl;
}

如果你想要所有可能的枚举类型的后备,你现在可以依赖SFINAE,因为这些是不同的重载函数:

template<typename T>
std::enable_if_t<std::is_enum<T>::value>
MyFunc(tag<T>)
{
    std::cout << "Fallback for enums only" << std::endl;
}

请注意,您不应直接使用接受标记特化作为入口点的MyFunc的含义.
这些都是内部功能.
请使用通用的,如示例中所示.

标签:specialization,c,c11,enums,templates
来源: https://codeday.me/bug/20190828/1756703.html