C++:用户定义的显式类型转换函数错误
C++ : user defined Explicit type conversion function error
代码如下所示:
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
类型的对象由于operator int
转换为int
类型,然后是class的转换构造函数调用 myClass
以创建 dummy
.
类型的对象
这是一个演示程序,展示了使用显式转换创建 class 对象的两种方法。
#include <iostream>
struct A
{
explicit A( int x = 0 ) : x( x ) { std::cout << "A( " << x << " )\n"; }
A( const A & ) { std::cout << "A( const A & )\n"; }
int x;
};
int main()
{
A a( 1 );
std::cout << '\n';
( A )a;
std::cout << '\n';
( A )2;
return 0;
}
程序输出为
A( 1 )
A( const A & )
A( 2 )
相对于你的程序,那么在你的程序中,在使用这些方法之前还有一个额外的步骤:类型 myClass
的对象将被初步转换为类型 dummy
或类型int
.
在 ubuntu 18.04 上使用 gcc-9 编译您的原始代码我明白了:
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&&)’
发生的事情是编译器无法判断你是想从 'myClass' 的 int 转换中创建一个新的 'dummy' class 还是一个新的 'dummy' 'dummy'.
的隐式生成的复制运算符
这会导致一个循环,其中 'myClass' 可以转换为 int
和 dummy
这意味着编译器在尝试转换 'myClass' 时卡住了,因为它不知道是什么你真的想做 - 转换为 'dummy',转换为 'dummy' 然后复制它,或者通过将 'myClass' 转换为 int
[=16 来制作一个新的 'dummy' =]
解决这个问题的方法是让你的转换运算符成为 int explicit
这可以防止编译器进行隐式转换并允许它工作(至少在 gcc-9 上)。
这是您的代码的更新副本,可以使用:
using namespace std;
class dummy{
public:
int x;
explicit dummy(int x=0) : x(x) {}
};
class myClass {
public:
explicit operator int(); // < Set to explicit
explicit operator dummy();
};
myClass::operator int() {
return 10;
}
myClass::operator dummy(){
return dummy(9);
}
int main() {
myClass mc1;
dummy val = static_cast<dummy>(mc1);
cout << "mc1 int cast: " << static_cast<int>(mc1) << endl;
cout << "val.x: :" << val.x << endl;
std::cin.get();
return 0;
}
这是用 gcc-9 和 clang++-9 编译的
作为旁注,请永远不要在 C++ 中使用 C 风格的转换,它们容易出错并且调试起来很麻烦
代码如下所示:
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
类型的对象由于operator int
转换为int
类型,然后是class的转换构造函数调用 myClass
以创建 dummy
.
这是一个演示程序,展示了使用显式转换创建 class 对象的两种方法。
#include <iostream>
struct A
{
explicit A( int x = 0 ) : x( x ) { std::cout << "A( " << x << " )\n"; }
A( const A & ) { std::cout << "A( const A & )\n"; }
int x;
};
int main()
{
A a( 1 );
std::cout << '\n';
( A )a;
std::cout << '\n';
( A )2;
return 0;
}
程序输出为
A( 1 )
A( const A & )
A( 2 )
相对于你的程序,那么在你的程序中,在使用这些方法之前还有一个额外的步骤:类型 myClass
的对象将被初步转换为类型 dummy
或类型int
.
在 ubuntu 18.04 上使用 gcc-9 编译您的原始代码我明白了:
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&&)’
发生的事情是编译器无法判断你是想从 'myClass' 的 int 转换中创建一个新的 'dummy' class 还是一个新的 'dummy' 'dummy'.
的隐式生成的复制运算符这会导致一个循环,其中 'myClass' 可以转换为 int
和 dummy
这意味着编译器在尝试转换 'myClass' 时卡住了,因为它不知道是什么你真的想做 - 转换为 'dummy',转换为 'dummy' 然后复制它,或者通过将 'myClass' 转换为 int
[=16 来制作一个新的 'dummy' =]
解决这个问题的方法是让你的转换运算符成为 int explicit
这可以防止编译器进行隐式转换并允许它工作(至少在 gcc-9 上)。
这是您的代码的更新副本,可以使用:
using namespace std;
class dummy{
public:
int x;
explicit dummy(int x=0) : x(x) {}
};
class myClass {
public:
explicit operator int(); // < Set to explicit
explicit operator dummy();
};
myClass::operator int() {
return 10;
}
myClass::operator dummy(){
return dummy(9);
}
int main() {
myClass mc1;
dummy val = static_cast<dummy>(mc1);
cout << "mc1 int cast: " << static_cast<int>(mc1) << endl;
cout << "val.x: :" << val.x << endl;
std::cin.get();
return 0;
}
这是用 gcc-9 和 clang++-9 编译的
作为旁注,请永远不要在 C++ 中使用 C 风格的转换,它们容易出错并且调试起来很麻烦