问题
I was pointed to the 'safe bool idiom', and after trying to decipher what is going on (the explanation supplied on the site was not sufficient enough to grant me understanding of why it works), I decided to try to take the following code apart and make an attempt at simplifying it as much as possible. The site supplied code below:
class Testable {
bool ok_;
typedef void (Testable::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
public:
explicit Testable(bool b=true):ok_(b) {}
operator bool_type() const {
return ok_==true ?
&Testable::this_type_does_not_support_comparisons : 0;
}
};
I decided to analyse the key basis of 'bool_type' given this seems to be what it's centred on. Given the following line:
typedef void (Testable::*bool_type)() const;
One can (not so easily, due to bracketing) deduce it's a typedef of a type of 'void Testable::*', of which bool_type represents. This can be further demonstrated by making the following modifications and function calls:
class Testable {
bool ok_;
typedef void (Testable::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
public:
explicit Testable(bool b=true):ok_(b) {}
bool_type Test; //Added this
operator bool_type() const {
return ok_==true ?
&Testable::this_type_does_not_support_comparisons : 0;
}
};
int main()
{
Testable Test;
int A = Test.Test; //Compiler will give a conversion error, telling us what type .Test is in the process
}
It allows us to see what type bool_type is:
error: cannot convert 'void (Testable::*)()const' to 'int' in initialization
Which shows it is indeed a type of 'void (Testable::*)'.
The issues crops up here:
If we modify the following function:
operator bool_type() const {
return ok_==true ?
&Testable::this_type_does_not_support_comparisons : 0;
}
And turn it into:
operator void Testable::* () const //Same as bool_type, right?
{
return ok_==true ?
&Testable::this_type_does_not_support_comparisons : 0;
}
It generates the following complaints:
error: expected identifier before '*' token
error: '< invalid operator >' declared as function returning a function
My questions are thus:
Why is it generating those complaints if 'void (Testable::*) is indeed the typedef for bool_type?
And
What is going on here?
回答1:
Your reasoning goes wrong about here
operator void Testable::* () const //Same as bool_type, right?
This isn't correct. The type of bool_type is, as the compiler tells us in the error message:
'void (Testable::*)()const'
So, to replace it in the operator, you would need something like
operator (void (Testable::*)() const) () const
if that is ever possible! See why even the ugly typedef is an improvement?
In C++11 we also have the new construct explicit operator bool()
to save us from this ugliness.
来源:https://stackoverflow.com/questions/7704395/how-does-the-safe-bool-idiom-bool-type-and-the-safe-bool-idiom-work