首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >clang std::isspace编译错误

clang std::isspace编译错误
EN

Stack Overflow用户
提问于 2018-01-16 12:17:55
回答 2查看 1.4K关注 0票数 4

下面的代码可以编译VS 2015(更新3)和gcc 6.3 (C++14),没有任何问题。

代码语言:javascript
复制
#include <string>
#include <locale>

int main()
{
    std::u16string ustr = u"Android";

    bool var = std::isspace(ustr[0],std::locale());

    return 0;
}

但是,在clang/Xcode上,它失败了,出现了以下错误

代码语言:javascript
复制
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.

我在这里错过了什么?有标头吗?如果是,是哪一个?如果没有,还有其他解决办法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-16 13:10:26

问题是std::isspacestd::locale实现使用了在std::ctype中定义的字符特征,这定义了字符类型的某些特性。

不幸的是,标准只要求std::ctype是专门针对charwchar_t的,而不是像您所需要的char16_t。看来MSVC和GCC正在提供额外的实现(因为这样做是有意义的)。(编辑:GCC实际上抛出了一个异常)。

我们不能为它添加我们自己的专门化,因为namespace.std声明我们只能为用户定义的类型向namespace std添加专门化。

这给我们留下了几个选择:

  • 在使用charwchar_t中的std::isspace之前,将角色转换为<locale>
    • 请注意,对于char,这通常是一种缩窄转换,您可能不希望这样做。

  • 切换到使用std::isspace的实现,从<cctype>转换为int
    • 如果不能在unsigned char中表示该类型,则您有未定义的行为,因此这也可能不是您想要的,这取决于您使用的类型(对照sizeof(unsigned char))。

  • 为你的角色类型写上你自己的特质(也许是现在最好的选择)
  • 提交一份缺陷报告,希望委员会同意你的意见,然后等待两年或更长时间才能修复:-)
    • 或者,请clang作者增加这种便利(也不是个坏主意)。

  • 编写您自己的专门化,就像@Holt做的那样,只需忍受未定义的行为。

相关:C++11中对Unicode的支持程度如何?

票数 5
EN

Stack Overflow用户

发布于 2018-01-16 12:31:44

std::isspace重载在<locale>中等价于(根据标准):

代码语言:javascript
复制
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>,所以我认为您在这里是完蛋了。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48281099

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档