-
template function
I have 2 functions here that do almost the same thing. One converts a string to wstring and the other wstring to string. Somehow I think I should create one template function for this but dont see how to do it. Anyone else have an idea on how to do this?
Code:
static std::string wide_to_char(const std::wstring &ws)
{
std::string s;
for (std::string::size_type i = 0; i < ws.length(); i++)
{
char c;
wctomb(&c, ws[i]);
s.push_back(c);
}
return s;
}
static std::wstring char_to_wide(const std::string &s)
{
std::wstring ws;
for (std::string::size_type i = 0; i < s.length(); i++)
{
wchar_t c;
mbtowc(&c, &s[i], 1);
ws.push_back(c);
}
return ws;
}
-
I do not think you can write a single template function for this as the usage patterns of wctomb and mbtowc are slightly different, so it is not just a matter of passing a function as an argument to be applied.
But, if you write wrappers for wctomb and mbtowc, you can then pass the appropriate wrapper function (or function object) as an argument to std::transform, instead of writing the loops by hand (and of course, you would then have increased flexibility, and retain the option of writing convenience functions that make use of these std::transform calls).
-
yeah probably. I came up with this but I think its more complex than just write 2 functions. Was hoping for a shorter/easier solution
Code:
static char exec(wchar_t from)
{
char c;
wctomb(&c, from);
return c;
}
static wchar_t exec(char from)
{
wchar_t c;
mbtowc(&c, &from, 1);
return c;
}
template<typename To, typename From>
To convert(const From &s)
{
To out;
for (From::size_type i = 0; i < s.length(); i++)
{
out.push_back(exec(s[i]));
}
return out;
}
-
Actually, I had this in mind:
Code:
char wide_to_char(wchar_t wc)
{
char c;
wctomb(&c, wc);
return c;
}
wchar_t char_to_wide(char c)
{
wchar_t wc;
mbtowc(&wc, &c, 1);
return wc;
}
std::string wide_to_string(const std::wstring& ws)
{
using namespace std;
string s;
transform(ws.begin(), ws.end(), back_inserter(s), wide_to_char);
return s;
}
std::wstring string_to_wide(const std::string& s)
{
using namespace std;
wstring ws;
transform(s.begin(), s.end(), back_inserter(ws), char_to_wide);
return ws;
}
If you prefer, the latter two convenience functions could be replaced by a convenience function template:
Code:
template<typename Dest, typename Source, typename Func>
Dest convert(const Source& source, Func func)
{
using namespace std;
Dest dest;
transform(source.begin(), source.end(), back_inserter(dest), func);
return dest;
}
which you can then call such as:
Code:
std::wstring ws;
// ...
std::string s = convert<std::string>(ws, char_to_wide);
-
yeah thats a nice solution. thanks!
-
Only if your wide chars don't actually require multiple chars to store, otherwise wctomb will overflow the given buffer and mbtowc will convert garbage.