I am trying to make utility for converting strings as I have a bad mix of interfaces needing strings in various containers (char*, std::string, custom string type) and formats (utf-8, utf-16, utf-32). So I had the idea to create a wrapper with cast operators to the various types. Like this:
#include <iostream>
#include <string>
struct X {
operator std::string() { return std::string("string x"); }
operator const char *() { return "zstring x"; }
};
X make_x() { return X(); }
int main()
{
std::string y = make_x(); // this works
std::string y(make_x()); // but this does not
y = make_x(); // this does not work either
y = std::string(make_x()); // nor does this, so it's about useless
std::cout << y << std::endl;
return 0;
}
But the problem is that if the type converts to both char *
and std::string
, the std::string
constructor and assignment will be ambiguous between those two types. And I don't want to go through just char *
, because the string may be originally given by range rather than as nul terminated, requiring extra copy to get a nul terminated one as well as making embedded nuls not work.
So is there any way to disambiguate these?
Important note: I am stuck with some C++03 compilers, so neither cast operator can be marked explicit.
I ended up creating one helper with cast operator to any character (char
, wchar_t
and either uint16_t
or uint32_t
depending on whether wchar_t
is 32 or 16 bit) pointer type and another helper with cast operator to any basic_string (specialized to any of above, using custom traits for the non-standard types). That does not appear to be ambiguous anywhere.