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.
Disambiguate cast operator when the target class has multiple constructors
-
31-05-2022 - |
Frage
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.
Lösung 2
Andere Tipps
Explicitly cast the result of make_x()
so std::string
, const char*
or whatever before passing it as a function argument, e. g.:
std::string y(static_cast<const char*>(make_x()));
If you need to do this a lot and consider it to verbose, give the cast operators short names:
struct X {
std::string str() { return std::string("string x"); }
const char *cstr() { return "zstring x"; }
};
std::string y(make_x().str());
If this is unacceptable too, adapt the safe bool idiom to your purpose.