7

当我尝试编译(使用 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的第二次重载 MyClass的转换运算符之一,我没有编译错误。

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

预先感谢您的任何帮助。

4

3 回答 3

4

from 的转换MyClass是不明确的,因为有一个到 enum 的转换int和一个到 enum 的转换,它本身可以隐式转换为int,并且两者都是同样好的转换。但是,您可以通过指定所需的转换来明确调用:

myfunc(int(MyClass()));

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

于 2011-09-15T16:22:45.523 回答
4

enums 是 C++ 中的类型,与 C 不同。

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


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

  • 当自定义转换的定义MyClass->int被删除时,代码编译。

  • 这里有 enum to 的隐式转换,int因此它是编译器偏爱的一种 to char在这里测试

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

  • 编译器尝试从 to 转换MyClasschar发现,没有用户定义的转换运算符char(),既是用户定义int()的,SimpleEnum()也可以使用。在这里测试

  • 当您char()为编译添加转换运算符时,MyClass会出现与未添加相同的错误。

  • 在这里测试

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

  1. MyClass通过int用户定义的转换运算符。
  2. MyClass通过int用户定义的转换 ( MyClassto SimpleEnum) + 隐式转换 ( SimpleEnumto char)

编译器不知道使用哪一个。

于 2011-09-15T16:16:23.727 回答
1

我本来希望调用 int 重载。尝试了一些编译器并得到了不同的结果。如果要删除任何内容,请将用户转换运算符删除为int,因为枚举具有到整数的标准转换。

于 2011-09-15T16:23:31.137 回答