这是代码的外观:
using namespace std;
class dummy{
public:
int x;
explicit dummy(int x = 0) : x{ this->x = x } {}; //explicit has no effect here
};
class myClass {
public:
operator int(); //<---problematic conversion
explicit operator dummy();
};
myClass::operator int() {
return 10;
}
myClass::operator dummy(){
return dummy(9);
}
int main() {
myClass mc1;
dummy val = (dummy)mc1;
cout << "mc1 int cast: " << mc1 << endl;
cout << "val.x: :" << val.x << endl;
std::cin.get();
return 0;
}
我在这里使用ms vs编译器,并获取c2440(类型转换错误)。据我了解,我在语法上没有做任何错误的事情。这里的问题是,如果我从代码中删除隐式转换:operator int()
及其相应的功能,它将可以正常工作。即:
using namespace std;
class dummy{
public:
int x;
explicit dummy(int x = 0) : x{ this->x = x } {}; //explicit has no effect here
};
class myClass {
public:
//operator int();
explicit operator dummy();
};
/*
myClass::operator int() {
return 10;
}*/
myClass::operator dummy(){
return dummy(9);
}
int main() {
myClass mc1;
dummy val = (dummy)mc1;
//cout << "mc1 int cast: " << mc1 << endl;
cout << "val.x: " << val.x << endl;
std::cin.get();
return 0;
}
这将产生以下输出(按预期):
val.x: 9
编辑:在第二个示例中缺少显式关键字。输出是相同的
dummy
类型的对象的创建方式之间存在歧义。
第一个是调用operator dummy
创建类型为dummy
的临时对象,然后由于显式强制转换而调用复制构造函数。
[第二个是由于myClass
将类型int
的对象转换为类型operator int
,然后调用类myClass
的转换构造函数以创建类型[ C0]。
在ubuntu 18.04上用gcc-9编译您的原始代码,我明白了:
dummy
正在发生的情况是编译器无法确定您是要从myclass的int转换中创建新的'dummy'类,还是要从隐式生成的'dummy'的复制运算符中创建新的'dummy'。
这会导致一个循环,其中“ myClass”可以同时转换为test.cpp:27:24: error: call of overloaded ‘dummy(myClass&)’ is ambiguous
27 | dummy val = (dummy)mc1;
| ^~~
test.cpp:7:14: note: candidate: ‘dummy::dummy(int)’
7 | explicit dummy(int x = 0) : x{ this->x = x } {}; //explicit has no effect here
| ^~~~~
test.cpp:4:7: note: candidate: ‘constexpr dummy::dummy(const dummy&)’
4 | class dummy{
| ^~~~~
test.cpp:4:7: note: candidate: ‘constexpr dummy::dummy(dummy&&)’
和int
,这意味着在构造虚拟对象时,编译器会卡住尝试对其进行转换,因为它不知道您实际要做什么-新建一个'dummy',创建一个新的'myClass'并将其转换为'dummy'或创建一个新的'myClass'并将其转换为int