VS2015中以下代码的输出是“构造函数”。
由于缺少赋值运算符,它不应该无法编译吗?
struct A { };
struct B {
B(){}
B(const A& a) {
cout << "constructor" << endl;
}
//B& operator=(const A& a) {
// cout << "assignment operator" << endl;
// return *this;
//}
};
int main() {
A a;
B b;
b = a;
return 0;
}
答案 0 :(得分:30)
是的,当转换正在进行时,就像在测试用例中一样。
您正在有效地致电
b = B(a);
因为隐式声明了B
的赋值运算符B& operator=(B const&)
,所以在重载解析期间会找到它。由于您的作业只是一次转换,而不是匹配(这恰好是允许发生的转化次数),因此会将a
转换为B
,然后分配新的临时B
} b
。
答案 1 :(得分:14)
让我们考虑一个类似的例子。
double a;
int b=5;
a=b;
您可以分配给double
的唯一内容是另一个double
。但是,int
可以转换为double
。
同样在这里,A
可以转换为B
,因为这样做的构造函数存在。这就是发生的事情。
答案 2 :(得分:11)
您的代码已从if(fileName.trim().contains(" "))
fileName.replace(" ","_");
隐式转换为A
,B
编译为b = a
。如果您希望将其检测为错误,可以使用the explicit
specifier:
b = B(a);
然后您应该收到错误,例如these generated by ideone.com:
struct B {
B(){}
explicit B(const A& a) {
std::cout << "constructor" << std::endl;
}
};
之后,永远不会隐式调用构造函数,如果要调用它,则必须明确地编写它:prog.cpp: In function 'int main()':
prog.cpp:20:7: error: no match for 'operator=' (operand types are 'B' and 'A')
b = a;
^
prog.cpp:5:8: note: candidate: B& B::operator=(const B&)
struct B {
^
prog.cpp:5:8: note: no known conversion for argument 1 from 'A' to 'const B&'
prog.cpp:5:8: note: candidate: B& B::operator=(B&&)
prog.cpp:5:8: note: no known conversion for argument 1 from 'A' to 'B&&'