Question

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.

Was it helpful?

Solution 2

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top