I’ve seen a nice trick made by an boost Implementation, they somehow use the overloading of the () operator to evaluate an instance of the class boost::system::error_code to an bool value
class error_code
{
...
typedef void (*unspecified_bool_type)();
static void unspecified_bool_true() {}
operator unspecified_bool_type() const // true if error
{
return m_val == 0 ? 0 : unspecified_bool_true;
}
...
}
This results in the possibility to check for an error like this
...
boost::system::error_code err
some_boost_func(err);
if(err)
{
//handle error
}
....
So i keep asking myself.. what happend there?
This seems to somehow relate to the use of function pointers…
What happens if i call err does this evaluate the function itself or the function pointer?
But how can a void (*unspecified_bool_type)(); function return a value in
return m_val == 0 ? 0 : unspecified_bool_true;
It really has little (or nothing) to do with core functionality of function pointers specifically. It is a trick that allows one to write a “safe” boolean-like conversion for the class.
When one wants some class to be usable under
if(and generally in logic contexts), one typically makes it convertible tobool. As inand now you can do
However, since
booltype is an integral type in C++, this might lead to undesirable consequences, when someone accidentally writes something likeor uses
errin an arithmetic expression and it quietly compiles.For this reason, in many cases people prefer to introduce a conversion to pointer type, instead of conversion to
bool, as inThis is better since one can use it under
if, but one can’t make the previous mistake withint. I.e.will compile and work as intended, since the compiler will automatically convert
errobject to pointer type.However, such conversion will be automatically applied in pointer contexts as well (in addition to boolean contexts), meaning that one can still accidentally do
or
and it will quietly compile. This is also undesirable.
To make it more difficult to accidentally misuse such error class, it is a good idea to use some more “exotic” pointer type, like pointer to a function. This is exactly what you see in the code you quoted. The
unspecified_bool_typeis used as a pointer-based pseudo-boolean type. Null value is returned forfalseand pointer to a dummyunspecified_bool_truefunction is returned fortrue. The functionunspecified_bool_trueis never called and never intended to be called. It only exists to reserve some unique pointer value to be used astruereturn.In some cases people take it one step further and use an even more “exotic” pointer type: pointer-to-class-member type. But for most applications pointer to function is “exotic” enough.