Reputation: 16765
I have though about operator overloading and come with an interesting code:
#include <iostream>
class A {
public:
operator bool() {
return true;
}
bool operator!() {
return false;
}
};
int main() {
A a;
if (!a) {
std::cout << "HELLO";
} else {
std::cout << "WORLD";
}
std::cout << std::endl;
return 0;
}
What will be called first and what after? And why? Is this described anywhere in the cppreference?
P.S. For downvoters and others who think I could not execute this code by myself. I could. I did. I have changed it many times to see it's behavior. So what? This is not an explanation. I have asked for a reference which clearly states what rule this code obeys. The information how it works on my machine does not answer the question - what if this is not even portable across different environments (OSes, maybe processors, and so on)?
Upvotes: 3
Views: 163
Reputation: 170193
How it works is simple. The compiler parses the source and sees if(!a)
. It then checks if A
defines an operator!
. Just so happens that it does. So that gets called.
If it had seen if(a)
it would have checked that an A
is convertible to something which can be used in the condition of an if
. Just so happens that it is indeed convertible.
If there had been no operator!
, the compiler would have instead checked that an A
can be converted to something which may be logically negated. Then the conversion to bool would have been performed.
BTW, the conversion will happen even in surprising places. For instance a + 1
will compile. Not what we want, I think. It's best to allow it only where a bool
is contextually expected. You do that by marking the conversion operator explicit:
explicit operator bool() {
return true;
}
Upvotes: 7
Reputation: 234795
!a
is no more than syntactic sugar for a.operator!()
, which you have defined: that's the compiler's preferred choice.
So the conversion to bool
operator is never a candidate.
You could contrive the latter by writing
if (!(bool)a) {
Upvotes: 4