Michał Ziobro Michał Ziobro - 2 months ago 9
C++ Question

Order of casting in C++

this is my first post here.

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

acs acs
Answer

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).