以下代码在XCode中编译,但在VS2008 / VS2010中不编译(错误:用户定义的模糊转换)。如果我使用函数而不是强制转换运算符,则它可以正常运行。这是VS的错误吗?
#include <stdio.h>
class A
{
public:
virtual operator int() const
{
return 1;
}
};
class B : public virtual A
{
public:
virtual operator int() const
{
return 2;
}
};
class C : public virtual A, public virtual B
{
public:
};
int main()
{
C c;
int i = (int)c;
printf("%d\n", i);
return 0;
}
答案 0 :(得分:3)
发生错误是因为编译器发现它可以用不同的方式执行操作,因为转换是隐式的,编译器必须选择“正确的方法”。
从您的情况开始:编译器无法真正执行类似
的操作(int) c;
它不知道如何,但是它可以将c转换成它知道如何转换为int的东西,但这留下了两个选项:
(int) A(c);
(int) B(c);
两者同样有效且非常不同!没有办法知道要实施哪个。实际上,如果你有一个B类型的变量b,你甚至可能会发现问题,因为你可以采用两种方式:
(int) b;
(int) A(b);
如果编译器选择了一种方法,你就不知道哪种方式,不同的编译器可以选择不同的选项! 那么有什么解决方案:
从B到A,C到B和C到A显式转换。然后创建一个 cast函数,首先将其转换为您想要的类,以及 然后将其转换为int。这虽然不适用于视觉 你正在使用的工作室,所以这对你的情况不起作用。
使B类受到保护,但由于您希望将C转换为B,因此不起作用。 由于将B转换为int的问题,您不能仅仅使A受保护。
在A中定义强制转换操作,但使其调用虚函数,即B 覆盖。这样,只有一个演员操作,在A中定义, 没有ambiguos案例。
我认为第三种选择在你的情况下是最好的,它看起来像:
#include <stdio.h>
class A
{
protected:
virtual int _int_cast() const
{
return 1;
}
public:
operator int() const
{
return this->_int_cast();
}
};
class B : public virtual A
{
protected:
virtual int _int_cast() const
{
return 2;
}
};
class C : public virtual A, public virtual B
{
public:
};
int main()
{
C c;
int i = (int)c;
printf("%d\n", i);
return 0;
}
基本上:不要从你继承的类中重新实现重载的强制转换,假设它必须首先转换为基类。还要注意非常类似的重载强制转换,例如,你可以转换为int,然后转换为const int,或者直接转换为const int。
答案 1 :(得分:2)
您是否可能在xcode中收到警告?我无法检查xcode中的代码,但我能够在VS2010中得到一个警告,并且有一个错误。
警告:
main.cpp(30): warning C4250: 'C' : inherits 'B::B::operator int' via dominance
main.cpp(19) : see declaration of 'B::operator int'
错误:
main.cpp(37): error C2440: 'type cast' : cannot convert from 'C' to 'int'
警告可能有助于解释您案件中的错误。警告在http://msdn.microsoft.com/en-us/library/6b3sy7ae%28v=vs.80%29.aspx处描述,我建议您仔细阅读。
至于错误,嗯,除了可能导致问题的继承之外,我不能100%确定。如果为c定义operator int,它将编译。