C++ user-defined conversion operators without classes?

Jean-Denis Muys picture Jean-Denis Muys · Oct 24, 2009 · Viewed 12.1k times · Source

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?

Answer

sbi picture sbi · Oct 24, 2009

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.