cxxomfort  rel.20210622
Simple backports for C++ - http://ryan.gulix.cl/fossil.cgi/cxxomfort/
explicit_cast

The cxxomfort library implements an emulation of the "explicit operator" feature of C++11 that allows classes to provide explicit conversion to a defined set of types. A customized conversion "cast" that works like C++>=11's explicit operator and is invoked explicitly via a pseudokeyword "<tt>explicit_cast</tt>". The implementation is built upon based on the explicit_cast implementation from Imperfect C++: Solutions for the Real World, and "adapted out" in C++11.

An example usage:

// lib code
class MyClass {
....
CXXO_EXPLICIT_OPERATOR(bool) () const {
...return a bool somehow
}
};
// client code
MyClass myobject;
...
if (explicit_cast<bool>(myobject)) {
...do something
} else {
...do something else
}

Generation

In order to invoke this feature, two special keywords are used:

Library code adds a special member function to the class using the macro CXXO_EXPLICIT_OPERATOR(target_type) to declare its signature (potentially adding cv-qualification), then continues with the body of the conversion operator.

Client code evaluates the conversion via the pseudokeyword explicit_cast<target_type>(variable).

When in a C++<11 context, using this feature resolves to a special function call that provides a bool ; when in C++>=11 context, it resolves instead to the native explicit operator bool().

Example result code for the above code in C++03:

class MyClass {
operator explicit_cast<bool> () const {
...return a bool somehow
}
};
if (explicit_cast<bool>(myobject)) {
....
} else {
....
}

Whereas resulting code in a C++>=11 context looks like this:

class MyClass {
explicit operator bool () const {
...return a bool somehow
}
}
if (static_cast<bool>(myobject)) {
....
} else {
....
}

Limitations

Because the feature is implemented as a pseudo-keyword, it can not be used to create variables at if(...) scope, as C++<03 does not have the ability to autoinvoke bool conversions in such contexts.

The solution is simple: implement the guard variable in an outer scope:

// This won't work in C++03 unless MyClass *implicitly* converts to bool
if (MyClass myobject = ....) { ...}
// This always work, in C++98, C++03, C++11, ...
{ MyClass myobject = ....;
if (explicit_cast<bool>(myobject)) { .... }
} // "myobject" dies at this point
See also
http://ryan.gulix.cl/fossil.cgi/cxxomfort/wiki?name=Features/explicit_cast