大多数情况下,我忘记了wchar_t文字的L前缀,或者我错误地将其放入char字面,似乎编译(g ++)并没有抱怨(没有错误,没有警告)我的计划按预期行事。
例如
char cString[] = "Hello World!";
*std::strchr(cString, L'W') = L'w';
std::cout << cString << std::endl;
和
wchar_t cWideString[] = L"Hello World!";
*std::wcschr(cWideString, 'W') = 'w';
std::wcout << cWideString << std::endl;
都工作。
这是因为,在这种情况下,&#39; W&#39;和&#39; w&#39;是单字节字符?
我很感兴趣,因为我想故意使用它,用于以下功能:
template<typename T> T* findNextSpace(T* str);
旨在用于T等于char
,const char
,wchar_t
或const wchar_t
。对于任何字符类型T?
' '
是否安全?
或者我应该使用类似(T)
的内容来将文字转换为正确的类型?
编辑:我知道它对char*
和wchar_t*
有所不同,但我的问题不是关于字符串文字,而是关于字符文字。
答案 0 :(得分:0)
这两种情况都属于隐式转换的规则。特别是整数转换的规则。对于所有情况as wchar_t
is at least as wide as a char
,应明确定义char
到whar_t
的隐式转换。如果wchar_t
的值为(或者如果值不是&#39;},则编译器可能会警告您从char
到wchar_t
的转换中数据丢失的风险。在编译时知道,在char
可表示的范围之外。
根据我的理解,整数转换规则适用于整数类型的prvalue表达式,字符是整数类型,文字(字符串文字除外)是prvalues,所以这就是为什么你看到你用字符文字看到的行为,虽然你没有用字符串文字看到它。
I don't have a version of the standard that I can look things up in, but I understand that cppreference is found to be a reasonable source of information。希望它是准确的,我正确地解释了规则。
至于你关于寻找下一个空间的问题,你应该把它分成一个单独的问题。有了这个说你应该使用std::isspace
/ std::iswspace
(除非你特别只想要' '
),然后让编译器根据T选择合适的函数:
#include <type_traits>
#include <cwctype>
#include <cctype>
template <class T>
T* findNextSpace(T* str) {
if constexpr(std::is_same_v<T, char>) {
//Use std::isspace
}
else if(std::is_same_v<T, wchar_t>) {
//Use std::iswspace
}
else {
static_assert("Not implemented");
}
}
如果您的编译器不支持此处使用的功能,您可以使用模板专业化实现类似的解决方案:
#include <cwctype>
#include <cctype>
template <class T>
struct isspace_helper;
template <>
struct isspace_helper<char> {
bool operator()(char c) const {
return std::isspace(c);
}
};
template <>
struct isspace_helper<wchar_t> {
bool operator()(wchar_t c) const {
return std::iswspace(c);
}
};
显然你也可以在std::string
上使用它(因为大多数人会建议您使用std::string
而不是char
/ wchar_t
数组,除非你有充分的理由不要):
#include <algorithm>
#include <string>
template <class CharT, class Traits, class Alloc>
auto findNextSpace(std::basic_string<CharT, Traits, Alloc>& str) {
return std::find(str.begin(), str.end(), isspace_helper<CharT>{});
}
如果您的编译器不支持auto
,您可以改为编写std::basic_string<CharT, Traits, Alloc>::iterator
。然后可能提供一个超载,接受const
的字符串 - 参考以获得良好的衡量标准。