我有一堆函数,它们都具有相同的名称,但是具有不同的参数(其中一些是模板,有些不是):
void f(int& a) { ... } // there are a few other arithmetic types as well void f(bool& a) { ... } templatevoid f(std::pair &a) { ... } template void f(T& a) { ... } // ...
除此之外,我还有一个枚举:
enum MyEnum { enumVal1, enumVal2 };
我实际上以为,如果现在调用MyEnum e = enumVal1; f(e);
,它将自动调用MyEnum
底层类型的重载。没有。而是,它生成一个编译器错误。
现在,我想定义一个模板函数来捕获所有枚举并调用适当的函数。
template{}> * = nullptr> void f(T &a) { /* cast to std::underlying_type and call f() */ }
不幸的是由于某种原因,这与现有的语言产生了歧义f(T& a)
。
我怎么解决这个问题?该解决方案必须对所有枚举有效(但对于类枚举无效)。
我使用gcc 4.9和clang 3.5编译我的代码。
The use of SFINAE doesn't provide a better versions for partial ordering but merely determines which overloads are available. That is, for enums there two equally good candidate functions of f()
resulting in an ambiguity. The easiest way to address this ambiguity is to SFINAE both candidates to be for mutually exclusive sets of types:
template{}> * = nullptr> void f(T &a) { // version not applicable for enums } template {}> * = nullptr> void f(T &a) { /* cast to std::underlying_type and call f() */ }
这并没有解决原来的问题,不过,因为调查员是没有左值。请注意,您的原始问题CANB所要解决不采取T&
作为参数,而是采取了T
,一个T const&
也可能是T&&
:enum
小号做转换为基本类型,但枚举标签是不是左值,不能绑定到非const
参考。
除非有充分的理由不这样做,否则我可能只会出现一个重载:
templatevoid f(T&& a) { // ... }