下面的代码可以编译VS 2015(更新3)和gcc 6.3 (C++14),没有任何问题。
#include <string>
#include <locale>
int main()
{
std::u16string ustr = u"Android";
bool var = std::isspace(ustr[0],std::locale());
return 0;
}但是,在clang/Xcode上,它失败了,出现了以下错误
Error(s):
source_file.cpp:8:10: warning: unused variable 'var' [-Wunused-variable]
bool var = std::isspace(ustr[0],std::locale());
^
In file included from source_file.cpp:2:
In file included from /usr/include/c++/v1/locale:182:
/usr/include/c++/v1/__locale:705:44: error: implicit instantiation of undefined template 'std::__1::ctype<char16_t>'
return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
^
source_file.cpp:8:21: note: in instantiation of function template specialization 'std::__1::isspace<char16_t>' requested here
bool var = std::isspace(ustr[0],std::locale());
^
/usr/include/c++/v1/__locale:427:53: note: template is declared here
template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype;
^
/usr/include/c++/v1/__locale:186:54: error: implicit instantiation of undefined template 'std::__1::ctype<char16_t>'
return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
^
/usr/include/c++/v1/__locale:705:12: note: in instantiation of function template specialization 'std::__1::use_facet<std::__1::ctype<char16_t> >' requested here
return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
^
source_file.cpp:8:21: note: in instantiation of function template specialization 'std::__1::isspace<char16_t>' requested here
bool var = std::isspace(ustr[0],std::locale());
^
/usr/include/c++/v1/__locale:427:53: note: template is declared here
template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype;
^
1 warning and 2 errors generated.我在这里错过了什么?有标头吗?如果是,是哪一个?如果没有,还有其他解决办法吗?
发布于 2018-01-16 13:10:26
问题是std::isspace的std::locale实现使用了在std::ctype中定义的字符特征,这定义了字符类型的某些特性。
不幸的是,标准只要求std::ctype是专门针对char和wchar_t的,而不是像您所需要的char16_t。看来MSVC和GCC正在提供额外的实现(因为这样做是有意义的)。(编辑:GCC实际上抛出了一个异常)。
我们不能为它添加我们自己的专门化,因为namespace.std声明我们只能为用户定义的类型向namespace std添加专门化。
这给我们留下了几个选择:
char或wchar_t中的std::isspace之前,将角色转换为<locale> char,这通常是一种缩窄转换,您可能不希望这样做。
std::isspace的实现,从<cctype>转换为int。unsigned char中表示该类型,则您有未定义的行为,因此这也可能不是您想要的,这取决于您使用的类型(对照sizeof(unsigned char))。
@Holt做的那样,只需忍受未定义的行为。发布于 2018-01-16 12:31:44
std::isspace重载在<locale>中等价于(根据标准):
std::use_facet< std::ctype<charT> >(loc).is(ctype_base::space, c)如您所见,这需要对给定的std::ctype进行专门化处理。
标准只提供std::ctype<char>和std::ctype<wchar_t>。因为char16_t是一个内置类型,所以您不能专门化std::ctype<char16_t>,所以我认为您在这里是完蛋了。
https://stackoverflow.com/questions/48281099
复制相似问题