C++ 专门针对枚举的函数

标签 c++ templates c++11 enums specialization

是否可以在 enum 上特化模板函数?

我看过笔记here如果模板函数不是枚举,则可以将其禁用,但这是否可能同时仍允许其他类型?

我下面的示例显示了 intfloatenum 的特化(它没有编译,因为它试图重载 >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;
}

请注意,您不应直接使用接受 tag 特化作为入口点的 MyFunc 的含义。
这些是内部函数。
请改用通用的,如示例所示。

关于C++ 专门针对枚举的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38945760/

相关文章:

c++ - 将 std::unique_ptr 与分配器一起使用

c++ - 通过模板或纯虚拟基类继承进行动态类型文件访问?

c++ - 带有模板参数的 decltype

c++ - 多个类型名的部分模板特化

C++ 使用 std::pair 模板特化定义树节点数据结构

.net - OpenCV多线程调用

C++如何提取字符串的第一个和其余部分?

c++ - 委托(delegate)构造函数不能有其他内存初始化器 - 错误

c++ - 如何使用接口(interface)从 C++ 中的模板强制使用通用数据类型?

c++ - 删除动态创建的对象