如何重载用于枚举的模板函数
How to overload a template function for use with enums?
我有很多函数,它们都有相同的名称,但有不同的参数(其中有些是模板,有些不是):
void f(int& a) { ... } // there are a few other arithmetic types as well
void f(bool& a) { ... }
template <class T1, class T2> void f(std::pair<T1, T2>&a) { ... }
template <class T> void f(T& a) { ... }
// ...
除此之外,我还有一个枚举:
enum MyEnum {
enumVal1, enumVal2
};
实际上,我认为如果现在调用MyEnum e = enumVal1; f(e);
,它会自动调用MyEnum
的底层类型的重载。事实并非如此。相反,它会生成一个编译器错误。
现在我想定义一个模板函数,它可以捕获所有枚举并调用相应的函数。
template <class T, std::enable_if_t<std::is_enum<T>{}> * = nullptr>
void f(T &a) { /* cast to std::underlying_type<T> and call f() */ }
不幸的是,由于某些原因,这与现有的f(T& a)
产生了歧义。
我该如何解决这个问题?解决方案必须对所有枚举有效(但不适用于类枚举)。
我使用gcc 4.9和clang 3.5编译代码。
SFINAE的使用并不能为部分排序提供更好的版本,而只是确定哪些重载可用。也就是说,对于枚举,f()
的两个同样好的候选函数导致歧义。解决这种模糊性的最简单方法是SFINAE两个候选者都是互斥类型集:
template <class T, std::enable_if_t<!std::is_enum<T>{}> * = nullptr>
void f(T &a) {
// version not applicable for enums
}
template <class T, std::enable_if_t<std::is_enum<T>{}> * = nullptr>
void f(T &a) {
/* cast to std::underlying_type<T> and call f() */
}
这并不能解决您最初的问题,因为枚举器不是lvalues。请注意,您最初的问题可以通过不将T&
作为参数,而是将T
、T const&
或可能的T&&
:enum
s转换为底层类型来解决,但枚举器标记不是左值,不能绑定到非const
引用。
除非有充分的理由不这样做,否则我可能只会选择一个过载:
template <typename T>
void f(T&& a) {
// ...
}
函数f
只接受(非常量)引用:
int main() {
auto e = enumVal1;
f(e);
return 0;
}
因此f(enumVal1)
失败。
相关文章:
- C++中构造函数中的枚举
- 是否有 Windows 用户空间函数来枚举连接的网络共享?
- 如何使用默认值为构造函数中的枚举赋值?
- 泛型枚举和其他类型的重载模板函数
- 在运行时使用枚举器值作为模板函数的模板参数的元程序
- 函数-本地枚举声明和 ADL 的交互
- 如何从枚举类值中指定模板函数参数中的数组大小?
- 是否可以使用泛型枚举类型作为函数的参数?
- 枚举模板函数一般调用
- 为什么C++不为枚举类型提供默认"operator>>"函数?
- 从枚举中选择适当的函数
- 如何为返回枚举元组的 C++ 函数编写 cython 包装器?
- 如何将带有"any"枚举的 std::map 传递给函数
- 将函数参数限制为某些枚举值
- C++ 成员函数的多个定义,基于枚举模板参数
- 类中的枚举在调用自己的函数时不会改变
- 将全球枚举的全局枚举更改为函数中的int值
- 枚举值依赖函数调用
- 是否可以将非枚举值作为枚举函数参数传递
- C++中的枚举 - 函数如何分配值