c ++转换运算符重载,枚举,整数和字符

时间:2011-09-15 16:09:08

标签: c++ enums operators overloading ambiguous

当我尝试编译(使用gcc 4.3.4)时,这段代码片段为:

enum SimpleEnum {
    ONEVALUE
};

void myFunc(int a) {
}

void myFunc(char ch) {
}

struct MyClass {
    operator int() const { return 0; };
    operator SimpleEnum() const { return ONEVALUE; };
};

int main(int argc, char* argv[]) {
    myFunc(MyClass());
}

我收到此错误:

test.cc: In function "int main(int, char**)":
test.cc:17: error: call of overloaded "myFunc(MyClass)" is ambiguous
test.cc:5: note: candidates are: void myFunc(int)
test.cc:8: note:                 void myFunc(char)

我想我(几乎)明白问题是什么,即(简化它)即使我说的是“char”和“enum”,它们都是整数,然后重载是模糊的。

无论如何,我真的不明白的是,如果我删除 myFunc 的第二次重载 OR MyClass的一个转换运算符,我没有编译错误。

由于这个问题我将要更改大量旧代码(我将代码从旧版本的HP-UX aCC移植到Linux下的g ++ 4.3.4),我想更好地理解整个事情是为了选择修改代码的最佳方法。

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

enums are types in C++,与C不同。

enum - >都有隐式转换。 charenum - > int。编译器只是不知道选择哪一个。


编辑:尝试不同的测试后:

  • 当自定义转化的定义MyClass - > int已删除,代码已编译。

  • 这里有枚举隐式转换为int,因此它是编译器优先于char的转换。 Test here

  • 当删除void myFunc(int)的定义时,编译失败。

  • 编译器尝试从MyClass转换为char并发现,如果没有用户定义的转化运算符char(),则可以使用用户定义的int()SimpleEnum()Test here

  • char()编译时添加MyClass转换运算符失败,并显示相同的错误。

  • Test here

因此,我在此提出的结论是,在您最初发布的代码中,编译器必须决定应调用myFunc的两个重载版本中的哪一个。 由于两种转换都是可能的:

    通过用户定义的转换运算符
  1. MyClassint
  2. MyClassint通过用户定义的转化(MyClassSimpleEnum)+隐式转化(SimpleEnumchar
  3. 编译器不知道要使用哪一个。

答案 1 :(得分:4)

MyClass的转换含糊不清,因为只有一个转换为int,一个转换为枚举,它本身可以隐式转换为int,两者都是同样好的转换。但是,您可以通过指定所需的转换来显式调用:

myfunc(int(MyClass()));

或者,您可能想重新考虑为什么您的函数具有intchar的单独重载,也许可以重新设计。

答案 2 :(得分:1)

我原以为会调用int重载。尝试了一些编译器,得到了不同的结果。如果您要删除任何内容,请将用户转化运算符移至int,因为枚举已标准转换为整数。