我正在尝试在跨平台应用程序中处理unicode时抽象出std :: string / std :: wstring的烦恼。作为我创建转换“模板”的基本内容之一:
#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);
我会使用os_string_type作为主“字符串类型”。但是输入是特定类型(const char*
或const wchar_t*
- 并且几个“os-specific”函数需要宽字符串或普通字符串。
对于我在上面模板中创建的那些“接口”。 - 如果os_string_type与输入/输出要求相同,则为默认模板。以及要进行转换的特定模板。
这似乎有效。然而,存在“次要”缺点:如所述输入是字符数组。呼叫:
string_conver<std::wstring>(const char*)
确实会调用而不是专业化。在处理自动类型转换之前,C ++似乎首先选择函数类型。 (我猜这是不可克服的。
然后我写了另一个专业:
template <>
std::wstring string_convert<std::wstring, char*>(const char* input);
然而,现在visual studio(2010)在编译时出现以下错误:
错误C2912:显式专业化; 'std :: wstring string_convert(const char *)'不是函数模板的特化
如何解决这个问题?
编辑:
char * const
显然是错误的 - 它来自const char*
(只有通过阅读“答案”才能改变)。我希望能够允许常量字符数组,我无法编辑数组中的数据。
更新代码
(紧跟宋元尧的帖子之后),但是我在这里张贴这个以供将来参考:
#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);
答案 0 :(得分:2)
参数input
的声明不匹配。
变化
template <>
std::wstring string_convert<std::wstring, char*>(char* const input);
到
template <>
std::wstring string_convert<std::wstring, char*>(char* const & input);
BTW:如果您尝试使用clang,则错误消息是明确的:
注意:候选模板被忽略:无法匹配'std :: basic_string
(char * const&amp;)'反对'std :: wstring(char * const)'
答案 1 :(得分:1)
我建议使用重载而不是添加另一个特化:
inline std::wstring string_convert(char const *s)
{
return string_convert<std::wstring, std::string>(s);
}
如果你的string_convert
函数在内部工作于char缓冲区,那么你可能会获得效率,让模板版本和这个版本都调用相同的内部函数。
NB。我不太清楚你打算如何使用这个功能 - 通常你会有一个转换为特定类型的功能,而不是&#34;切换&#34;字符串的类型。
答案 2 :(得分:0)
我会这样做:
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; }
并允许从const char*
到std::string
的转换完成工作(因为const char*
不是模板参数)。