函数模板专业化 - 指针问题

时间:2014-07-14 07:52:47

标签: c++ string templates unicode

我正在尝试在跨平台应用程序中处理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);

3 个答案:

答案 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*不是模板参数)。