C++ 博尔兰C++;类型转换覆盖-为什么不明确?

C++ 博尔兰C++;类型转换覆盖-为什么不明确?,c++,casting,c++builder,C++,Casting,C++builder,我有以下枚举定义: typedef enum MyEnumBase { VALUE0 = 0, VALUE1, VALUE2, VALUE3 } MyEnum; 我的类使用此枚举的方式如下: class MyClass { public: MyClass (MyEnum initvalue) {enum1 = initvalue;}; operator bool() {return (VALUE0 == enum1);}; operator MyEnum() {re

我有以下枚举定义:

typedef enum MyEnumBase
{
  VALUE0 = 0,
  VALUE1,
  VALUE2,
  VALUE3
} MyEnum;
我的类使用此枚举的方式如下:

class MyClass {
public:
  MyClass (MyEnum initvalue) {enum1 = initvalue;};
  operator bool() {return (VALUE0 == enum1);};
  operator MyEnum() {return (enum1);};
private:
  MyEnum enum1;
};
具有以下主要功能:

int main(int agrc, char *argv[])
{
  MyClass class1 = VALUE2;

  bool OK = (VALUE0 == class1);

  return 0;
}
它使用MS VC++2010进行编译,但Borland XE2和XE3告诉我:

[bcc32 Error] test.cpp(26): E2015 Ambiguity between 'operator MyClass::bool()' and 'operator MyClass::MyEnumBase()'
我猜可能有歧义,但另一方面,左边的参数是MyEnum类型的,直接进行枚举转换而不是类的布尔转换。(就像VisualStudio那样)

如果我交换参数(class1==VALUE0),问题仍然存在

可以将该行修改为:

bool OK = (VALUE0 == (MyEnum)class1);
它可以编译,但在这种情况下,我必须检查整个庞大的项目,并“纠正”类的每一个用法-这不是一个好主意,因为这是我们的“错误变量”,它被过度使用


必须有一种更优雅的方法来编译这个文件。有人有想法吗?

伯兰的编译器显然是错的。因此,无论你做什么,都必须是编译器错误的解决办法,这让它很烦人,因为没有好的“这是你应该做的优雅的事情”解决方案:优雅的事情就是你当前正在做的事情,它会触发错误。对于一个问题,很少有不止一个优雅的解决方案

因此,首先要做的是提交一份bug报告


然后,您可以考虑一件事:除了比较之外,您还需要转换到enum吗?如果不是(或者如果这种情况很少见),考虑MyClass和MyNUM之间的重载。

Borland的编译器在这里显然是错误的。因此,无论你做什么,都必须是编译器错误的解决办法,这让它很烦人,因为没有好的“这是你应该做的优雅的事情”解决方案:优雅的事情就是你当前正在做的事情,它会触发错误。对于一个问题,很少有不止一个优雅的解决方案

因此,首先要做的是提交一份bug报告


然后,您可以考虑一件事:除了比较之外,您还需要转换到enum吗?如果不是(或者如果这种情况很少见),请考虑重载MyClass和MyNUM之间的比较。

避免使用转换运算符和非(?)显式构造函数,使用相同的类型!显式MyClass(MyEnum initvalue)enum1(initvalue){}应该修复它。

避免使用转换运算符和采用相同类型的非(!)显式构造函数!显式MyClass(MyEnum initvalue)enum1(initvalue){}应该修复它。

代表tebe回答:
由于我无法给出更清晰的结论性答案,我将我的想法发布在这里:


解决方案是为MyEnum和MyClass参数重载全局
运算符==

代表tebe回答:
由于我无法给出更清晰的结论性答案,我将我的想法发布在这里:


解决方案是为MyEnum和MyClass参数重载全局
运算符==

重载枚举和类之间的比较听起来是个不错的计划。-但是有一个但是。在这种情况下,我必须交换代码中的所有比较,因为比较是从左到右的。因此,编译器仍然希望强制转换该类。另一方面,根据我们的编码标准(在示例中不可见;),在比较的情况下,常数是左侧参数。-但是如果我找不到任何解决方法,我只需要交换参数。@user2667821-重载函数不必是成员函数
bool操作符==(MyEnum,constmyclass&)
可以正常工作。但是请看@DieterLücking的答案。重载枚举和类之间的比较听起来是个不错的计划但是有一个但是。在这种情况下,我必须交换代码中的所有比较,因为比较是从左到右的。因此,编译器仍然希望强制转换该类。另一方面,根据我们的编码标准(在示例中不可见;),在比较的情况下,常数是左侧参数。-但是如果我找不到任何解决方法,我只需要交换参数。@user2667821-重载函数不必是成员函数
bool操作符==(MyEnum,constmyclass&)
可以正常工作。但是请看@DieterLücking.给出的答案,并更清楚地说明它:模糊性在于
VALUE0==class1
可以通过将
class1
转换为枚举(使用转换运算符)或将
VALUE0
转换为
MyClass
(使用构造函数)来计算产生同样的问题-不管我没有带布尔参数的构造函数。borland是否将
false
解释为int(0)作为VALUE0?另一方面,添加操作符
bool操作符==(MyClass class2){return enum1==class2.enum1;}不能解决问题。我知道了。。。重载my Type的全局运算符==就解决了这个问题。更清楚地说,歧义在于
VALUE0==class1
可以通过将
class1
转换为枚举(使用转换运算符)或将
VALUE0
转换为
MyClass
(使用构造函数)来计算.行
bool OK=(false==class1)产生同样的问题-不管我没有带布尔参数的构造函数。borland是否将
false
解释为int(0)作为VALUE0?另一方面,添加操作符
bool操作符==(MyClass class2){return enum1==class2.enum1;}不能解决问题。我知道了。。。重载my类型的全局运算符==可以解决这个问题。