作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
是否可以在 enum
上特化模板函数?
我看过笔记here如果模板函数不是枚举,则可以将其禁用,但这是否可能同时仍允许其他类型?
我下面的示例显示了 int
、float
和 enum
的特化(它没有编译,因为它试图重载 >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/
我是一名优秀的程序员,十分优秀!