错误:模糊的默认类型转换(c ++)

时间:2011-04-07 00:31:36

标签: c++ gcc

我有一个包装枚举的类,便于打印,序列化等。
我希望能够在switch语句中使用它作为传统的枚举,因此我使用了int()overloader直到gcc-4.3。但是我的代码现在用 gcc-4.5.1 打破了。

enum E { consta, constb };
class Wrap {
 private:
  E e;
 public:
  operator E() { return e;}
  operator E() const { return e;}
  operator int() const { return e;} 
  Wrap(E a) : e(a) { }
};

int main() {
  Wrap x(constb);
  x = consta;
  switch (x) { /* Error here */
    case consta: // ..
    case constb: // ..
  }   
  return 0;
} 

编译器错误是:
错误:来自'Wrap'的模糊默认类型转换
错误:候选转换包括'Wrap :: operator E()const'和'Wrap :: operator int()const'

这是库的一部分,我希望代码可以在所有版本上运行,因此删除int overloader不是一个选项。

5 个答案:

答案 0 :(得分:0)

您可以使用static_cast

自行选择转化来解决歧义
switch(static_cast<E>(x))

另一个选择是创建一个或多个转换运算符explicit - 这将通过限制编译器的选项来解决歧义。

但是,explicit转换运算符仅适用于编译器不支持的C ++ 0x。

答案 1 :(得分:0)

将行更改为

switch ((E)x) {

枚举器和整数在编译器中非常相似(并且可能在内存中相同),因此这两者都令人困惑。如果您专门投射它,这里不会有任何您想要使用的歧义。

答案 2 :(得分:0)

C ++不允许您自动从枚举转换为int,导致operator int不需要(例如,它会使用E转换,然后转换为{{ 1}})?我知道你说你不想删除它,但你确实确认它破坏了API兼容性吗?

如果这不是一个选项,最好的办法是添加intas_int方法,以便在所需转化类型不明确的情境中使用。

答案 3 :(得分:0)

如果你专门解决编译器错误,只需使用条件编译来创建一个变通方法,并尽可能保持自包含。

#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) <= 40300
    typedef int E; // workaround
#   define ENUM_TYPE // do not define an enum type as it's not fully supported
#else
#   define ENUM_TYPE E // newer GCC supports enum better
#endif

enum ENUM_TYPE { consta, constb };
#undef ENUM_TYPE

...在此之后,您可以忘记解决方法,只需要一个操作员......

  operator E() const { return e;}

答案 4 :(得分:0)

规范说明条件(转换值):

  

条件应为整数类型,枚举类型或类型,其中存在单个转换函数为积分或枚举类型。

您的类类型有3个转换函数到积分或枚举类型,因此它很容易失败。如果删除operator int重载,它甚至不起作用,因为那时仍然有2个转换函数。没有重载解决方案。如果它不写任何东西

,也不需要非const operator E重载

明确的演员阵容将是一个安全的赌注。同样奇怪的方法是使用op+,但出于清晰原因我不会采取这种方式

switch (+x) { /* Don't do this in the wild */
  case consta: // ..
  case constb: // ..
}