I would like to ask about casting in C++. I heard that when casting is ambiguous compiler should return an error, but, just for better understanding, I tested it and it didn't, moreover, it used functions in quite weird order. When:
A foo;
B bar = foo;
it used casting operator, but when I typed:
bar = static_cast<B>(foo);
it used single argument constructor.
Can anyone explain why it acts in this way?
The whole code which I used:
#include <iostream>
#include <typeinfo>
using namespace std;
class B;
class A {
public:
A() {}
A (const B& x);
A& operator= (const B& x);
operator B();
};
class B {
public:
B() {}
B (const A& x) {
cout << "constructor B" << endl;
}
B& operator= (const A& x) {
cout << "Assign B" << endl;
return *this;
}
operator A() {
cout << "Outer B" << endl;
return A();
}
};
A::A (const B& x) {
cout << "constructor A" << endl;
}
A& A::operator= (const B& x) {
cout << "Assign A" << endl;
return *this;
}
A::operator B() {
cout << "Outer A" << endl;
return B();
}
int main ()
{
A foo;
// First one
B bar = foo;
bar = foo;
foo = bar;
// Second one
bar = static_cast<B>(foo);
B bar2 = static_cast<B>(foo);
foo = static_cast<A>(bar);
B bar3 = foo;
A foo2 = bar3;
A foo3 = B();
foo3 = B();
return 0;
}
Edit:
My output:
Outer A
Assign B
Assign A
Copy constructor B
Copy constructor B
Copy constructor A
Outer A
Outer B
Outer B
Assign A
The reason your compiler does not complain about ambiguity is that your constructors and assignment operators take a const A/B&
, but operator A()
and operator B()
are not declared const. For the conversion of non-const objects, the compiler therefore prefers operator A/B()
.
I think that the rest can be explained with the rules of static_cast
conversion, which in your code amounts to behavior as in direct initialization, and overload resolution (which is why the assignment operator is only called in the last example).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With