In C++ is it possible to define conversion operators which are not class members? I know how to do that for regular operators (such as +), but not for conversion operators.
Here is my use case: I work with a C Library which hands me out a PA_Unichar *
, where the library defines PA_Unichar to be a 16-bit int. It is actually a string coded in UTF-16. I want to convert it to a std::string
coded in UTF-8. I have all the conversion code ready and working, and I am only missing the syntactic sugar that would allow me to write:
PA_Unichar *libOutput = theLibraryFunction();
std::string myString = libOutput;
(usually in one line without the temp variable).
Also worth noting:
I know that std::string
doesn't define implicit conversion from char*
and I know why. The same reason might apply here, but that's beside the point.
I do have a ustring
, subclass of std::string
that defines the right conversion operator from PA_Unichar*
. It works but this means using ustring
variables instead of std::string
and that then requires conversion to std::string
when I use those strings with other libraries. So that doesn't help very much.
Using an assignment operator doesn't work as those must be class members.
So is it possible to define implicit conversion operators between two types you don't control (in my case PA_Unichar*
and std::string
), which may or may not be class types?
If not what could be workarounds?
What's wrong with a free function?
std::string convert(PA_Unichar *libOutput);
std::string myString = convert(theLibraryFunction());
Edit answering to the comment:
As DrPizza says: Everybody else is trying to plug the holes opened up by implicit conversions through replacing them with those explicit conversion which you call "visual clutter".
As to the temporary string: Just wait for the next compiler version. It's likely to come with rvalue references and its std::string
implementation will implement move semantics on top of that, which eliminates the copy. I have yet to see a cheaper way to speedup your code than than by simply upgrading to a new compiler version.
I don't think you can define "global" conversion operators. The standards say that conversion functions
are special member functions
. I would propse the following if I could consider the following syntax sugar:
struct mystring : public string
{
mystring(PA_Unichar * utf16_string)
{
// All string functionality is present in your mystring.
// All what you have to do is to write the conversion process.
string::operator=("Hello World!");
string::push_back('!');
// any string operation...
}
};
Be aware that polymorphic behavior of this class is broken. As long as you don't create an object of it through a pointer of type string*
though, you are in the safe-side! So, this code is perfect:
mystring str(....);
As said before, the following code is broken!
string* str = new mystring(....);
....
delete str; // only deleting "string", but not "mystring" part of the object
// std::string doesn't define virtual destructor
Implicit conversions are the devil, anyway. Make it explicit with a converting function call.
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