以下代码在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.
我在这里缺少什么? 任何标题包含?如果是这样,那是哪一个? 如果没有,还有其他解决方法吗?
答案 0 :(得分:5)
<locale>
中的std::isspace
重载相当于(按标准):
std::use_facet< std::ctype<charT> >(loc).is(ctype_base::space, c)
如您所见,这需要针对给定的std::ctype
进行CharT
的特化。
该标准仅提供std::ctype<char>
和std::ctype<wchar_t>
。由于char16_t
是内置类型,因此您无法对std::ctype<char16_t>
进行专门化,因此我认为您已被搞砸了。
答案 1 :(得分:3)
问题是std::locale
的{{1}}实现使用了std::ctype
中定义的字符特征,它们定义了字符类型的某些特征。
不幸的是,标准只要求std::isspace
专门用于std::ctype
和char
,而不是wchar_t
。似乎MSVC和GCC正在提供额外的实现(因为它是有意义的)。 (编辑:GCC实际上会抛出异常)。
我们无法为它添加自己的专门化,因为[namespace.std]声明我们只能将用户定义类型的特化添加到char16_t
。
这给我们留下了一些选择:
namespace std
中的char
之前,将您的角色投放到wchar_t
或std::isspace
<locale>
,这通常是缩小转化,您可能不希望char
std::isspace
的实施方案,其中<cctype>
投射到int
。
unsigned char
内表示您有未定义的行为,那么这可能也不是您想要的,具体取决于您使用的类型(请查看sizeof(unsigned char)
)@Holt
,并且只是处理未定义的行为