Well I am trying to abstract away the std::string/std::wstring annoyances when handling unicode in cross platform applications. As one of the basic things I created a conversion "template":
#ifdef _WIN32
typedef std::wstring os_string_type;
#else
typedef std::string os_string_type;
#endif
template <typename OSS_Ty, typename IN_Ty>
OSS_Ty string_convert(const IN_Ty& input);
template <>
std::wstring string_convert<std::wstring, std::string>(const std::string& input);
template <>
std::string string_convert<std::string, std::wstring>(const std::wstring& input);
I would use os_string_type as main "string type". However the input is a specific type (either const char*
or const wchar_t*
- and several "os-specific" function require either a wide string or a normal string.
So for those "interfaces" I created above templates. - The default template if os_string_type is the same as the input/output requirements. And the specific templates to do the conversion.
This seemed to work. However there is a "minor" drawback: as said the input is a character array. Calling:
string_conver<std::wstring>(const char*)
does invoke however not the specialization. C++ seems to first choose the function type before handling automatic type conversion. (Which I guess is unsurmountable.
So then I wrote another specialization:
template <>
std::wstring string_convert<std::wstring, char*>(const char* input);
However now visual studio (2010) gave the following error on compiling:
error C2912: explicit specialization; 'std::wstring string_convert(const char *)' is not a specialization of a function template
How to solve this?
EDIT:
the char * const
is obviously wrong - it came from const char*
(and only changed through reading an "answer" here). I wish to be able to allow constant character arrays where I can't edit the data in the array.
UPDATING code
Actual solution
(which follows quite directly from songyuanyao's post), but I'm posting this here for future references:
#ifdef _WIN32
typedef std::wstring os_string_type;
#else
typedef std::string os_string_type;
#endif
typedef char* char_array;
typedef const char* const_char_array;
typedef wchar_t* wchar_array;
typedef const wchar_t* const_wchar_array;
template <typename OSS_Ty, typename IN_Ty>
OSS_Ty string_convert(const IN_Ty& input);
template <>
std::wstring string_convert<std::wstring, std::string>(const std::string& input);
template <>
std::string string_convert<std::string, std::wstring>(const std::wstring& input);
template <>
std::wstring string_convert<std::wstring, const_char_array>(const const_char_array& input);
std::string -> std::wstring
as well asstd::string -> std::string
overload, if I were to "ignore" the type at other places. If the function would only be "conversion" in the true sense it would mean I have to add platform specific (convert vs non convert) at other places in the code - which I'm trying to prevent. – paul23