用于从 ANSI 字符串转换为 std::basic_string <TCHAR>的正确函数声明
A proper function declaration for conversion from ANSI string to std::basic_string<TCHAR>
我试图声明一个函数,该函数通过以下方式将const char *转换为std::basic_string:
#include <string>
#include <cstring>
#ifdef _MSC_VER
#include <tchar.h>
#else
#define TCHAR char
#endif
typedef TCHAR Char;
typedef std::basic_string<Char> String;
template <typename = typename std::enable_if< !std::is_same<Char, char>::value >::type >
inline String FromACString(const char * p_src)
{
String dest(std::strlen(p_src), ' ');
auto p_cur = p_src;
for (auto & ch : dest)
{
ch = *p_cur++;
}
return dest;
}
template <typename = typename std::enable_if< std::is_same<Char, char>::value >::type >
inline String FromACString(const char * p_src)
{
return p_src;
}
但得到编译器错误。我的想法是有两个重载,并根据 TCHAR 类型启用其中一个。正确的方法是什么?
VC2017 的错误是:
error C2995: 'String FromACString(const char *)': function template has already been defined
迈尔斯回答了你的enable_if
出了什么问题。但是,您可以使用if constexpr
来避免enable_if
的细微差别:
inline std::basic_string<TCHAR>
FromACString(const char * p_src)
{
if constexpr (std::is_same_v<TCHAR, char>) {
// logic for case where TCHAR is char
} else {
// logic for case where TCHAR isn't char
}
}
附言。您向wchar_t
的 TCHAR 转换(我认为这是除了char
之外唯一可能的其他可能类型(可能应该考虑字符编码。你可以使用 mbsrtowcs。
您的代码有两个问题:
- SFINAE 仅在依赖上下文中工作。 由于
typename std::enable_if<!std::is_same<Char, char>::value>::type
中的任何内容都不依赖于任何模板参数,因此 SFINAE 不适用,并且由于std::enable_if<false>::type
无效,因此会出现硬错误。 - 在确定模板的"唯一性"时,仅考虑参数类型本身,而不考虑其默认值。 函数模板有两个定义
template <typename> String FromACString(const char*)
,这是一个错误。
要解决第一个问题,您可以引入另一个默认值为Char
的模板参数。 第二个问题的通常解决方法是使用enable_if
表达式本身作为模板参数类型,而不是默认值。 这给你留下了这样的东西:
template <typename C = Char,
std::enable_if_t<!std::is_same<C, char>::value>* = nullptr>
String FromACString(const char* p_src) {
//...
}
template <typename C = Char,
std::enable_if_t<std::is_same<C, char>::value>* = nullptr>
String FromACString(const char* p_src) {
//...
}
现场演示
现在,根据Char
的定义方式,您最终会得到一个带有签名的模板
template <typename, void*>
String FromACString(const char*);
另一个是畸形的,因此被SFINAE禁用。
相关文章:
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中