This code compiles and runs with either a public implicit bool cast (commented out below, at http://ideone.com/FDJHB) or through a public implicit int cast followed by an implicit int to bool cast (as shown below, http://ideone.com/kHQ46). However, making the bool cast private (commented out below, at http://ideone.com/4poze) causes a compilation error. Why is the route through int no longer an option in that case? Do sequential casts like this have defined behavior? Thanks.
http://ideone.com/kHQ46
#include <iostream>
class MyObject {
public:
MyObject(int theInt) : theInt_(theInt) {
return;
}
MyObject& operator=(MyObject& source) {
std::cout << "assign op" << std::endl;
theInt_ = source.theInt_;
return *this;
}
friend MyObject operator*(MyObject& lhs, MyObject& rhs);
operator int() {
std::cout << "int conv" << std::endl;
return theInt_;
}
/*
operator bool() {
std::cout << "bool conv" << std::endl;
return theInt_;
}
*/
private:
int theInt_;
MyObject(MyObject& source);
// operator bool();
};
MyObject operator*(MyObject& lhs, MyObject& rhs) {
std::cout << "mult op" << std::endl;
return MyObject(lhs.theInt_*rhs.theInt_);
}
int main(int argc, char* argv[]) {
MyObject a(1);
MyObject b(2);
MyObject c(3);
if (a * b = c) std::cout << "Oh-no!" << std::endl;
return 0;
}
EDIT: As requested, the relevant compiler messages.
1) Output for the code as given, cast to int to bool:
mult op
int conv
assign op
int conv
Oh-no!
2) Output for the code with public bool cast:
mult op
int conv
assign op
bool conv
Oh-no!
3) Compiler error if bool cast made private:
prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:34: error: ‘MyObject::operator bool()’ is private
prog.cpp:50: error: within this context
In order to convert your type to bool, the compiler selects the "best" conversion path according to a (fairly complicated) set of rules.
If operator bool() is defined, then that provides a better conversion than operator int() followed by a conversion from int to bool; a path with fewer conversions is regarded as "better".
Accessibility isn't taken into account in this process, so it will choose operator bool() even though it is private. Then compilation will fail, because operator bool() is private.
In short, the compiler picks which method to call first, then checks to see if it's allowed to execute it. When it can see the operator bool that's the best match for an if check, so it picks that one and then discovers that it's private and can't be used.
Also note that (a * b = c) assigns c to the temporary returned from the multiplication and then evaluates whether that's zero or nonzero. I can't think of a scenario where such a thing would be useful.
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