Reputation: 9435
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
(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);
Upvotes: 1
Views: 637
Reputation: 217245
I would do this way:
template <typename OSS_Ty>
OSS_Ty string_convert(const std::string& input);
template <typename OSS_Ty>
OSS_Ty string_convert(const std::wstring& input);
template <>
std::wstring string_convert(const std::string& input) { /* Do the conversion */ }
template <>
std::string string_convert(const std::wstring& input) { /* Do the conversion */ }
template <>
std::string string_convert(const std::string& input) { return input; }
template <>
std::wstring string_convert(const std::wstring& input) { return input; }
and let the conversion from const char*
to std::string
do the job (as const char*
is not a template parameter).
Upvotes: 0
Reputation: 172924
The declaration of parameter input
mismatched.
change
template <>
std::wstring string_convert<std::wstring, char*>(char* const input);
to
template <>
std::wstring string_convert<std::wstring, char*>(char* const & input);
BTW: If you tried with clang, the error message is explicit:
note: candidate template ignored: could not match 'std::basic_string
(char *const &)' against 'std::wstring (char *const)'
Upvotes: 2
Reputation: 141554
I would suggest using an overload instead of adding another specialization:
inline std::wstring string_convert(char const *s)
{
return string_convert<std::wstring, std::string>(s);
}
If your string_convert
function internally works on char buffers then you might gain efficiency to have both the template version and this version call the same internal function.
NB. I don't quite see how you plan to use this function -- normally you would have a function that converts to a particular type, as opposed to "toggling" the type of the string.
Upvotes: 1