How can operator bool() cause an error when declaring operator std::string in a class and also serving as an implicit conversion to string by itself?
#include <iostream>
#include <string>
using namespace std;
class Test {
public:
operator std::string() { cout << "op string" << endl; return "whatever";}
operator bool() { cout << "op bool" << endl; return true;}
};
int main(int argc, char *argv[]) {
string s;
Test t;
s = t;
}
The problem you are facing (besides
operator std::string()returning a bool) is that implicit conversions trigger when you want and when you don’t.When the compiler sees
s = tit identifies the following potentialstd::operator=matches:Now,
tis neither of them, so it tries to convert it to something that can fit and finds two paths: convert to bool that can be promoted tocharor convert tostd::stringdirectly. The compiler cannot really decide and gives up.This is one of the reasons that you want to avoid providing many different conversion operators. Anything that can be implicitly called by the compiler will eventually be called when you don’t think it should.
This article specifically deals with this problem. The suggestion is instead of providing a conversion to
bool, provide a conversion to a member functionIf an instance of this class is used inside a condition (
if (testable())) the compiler will try and convert tobool_typethat can be used in a condition.EDIT:
After the comment on how the code is more complex with this solution, you can always provide it as a generic small utility. Once you provide the first part of the code, the complexity is encapsulated in the header.
Your class now becomes much more simple, and it is readable in itself (by choosing appropriate names for the functions and types):
Only if the reader is interested in knowing how the
safe_boolidiom is implemented and reads the header they fill be faced with the complexity (which can be explained in comments)