【问题标题】:When should I use a derived class facet in lieu of a base class facet?什么时候应该使用派生类方面来代替基类方面?
【发布时间】:2013-07-24 01:23:18
【问题描述】:

C++ 标准库中有一些标准基类方面,其默认行为取决于经典的“C”语言环境 (std::locale::classic())。如果您的程序需要特定于文化的功能,那么切换到派生类方面(又名byname 方面)是合理的,其行为取决于其构造时指定的语言环境。

例如std::ctype提供经典的“C”字符分类:

§22.4.1.3.3

   static const mask* classic_table() noexcept;

返回:指向大小为table_size 的数组的初始元素的指针,它表示“C”语言环境中字符的分类

这是否意味着std::ctype 的行为在功能上不同于它所安装的语言环境?例如,假设我有一个日语语言环境:

std::locale loc("ja_JP");

我想使用一个对日文字符进行字符分类的构面。字符分类是std::ctype的作用:

auto& f = std::use_facet<std::ctype<char>>(loc);

fctype 方法会根据日语语言环境还是经典的“C”语言对字符进行分类?我的第一个猜测是基于上面标准引用的“C”语言环境,但实际上它是日语语言环境。我想知道为什么引用与这里发生的事情不一致。

这是我的问题:

  • 为什么标准说 ctype 执行“C”字符分类,而 ctype 实际上是根据使用的语言环境进行分类的?

  • 既然上面是真的,那么派生类的切面又是从哪里来的呢?当基类已经使用我想要的语言环境时,为什么还要使用派生类方面?

【问题讨论】:

    标签: c++ locale


    【解决方案1】:

    只有 default-constructed std::ctype&lt;char&gt; facet 使用 classic_table 进行分类。从系统提供的"ja_JP" 获得的构面不是这样的例子。

    在谈论派生方面时,人们通常指的是从 std::ctype 等派生的用户定义方面,而不是系统提供的byname 方面。如果您想重新定义某些字符类,您可以使用派生的ctype facet,例如,将逗号视为空格以解析逗号分隔的输入流,或停止将空格和制表符视为空格,以解析流线-逐行。

    【讨论】:

    • 默认构造是什么意思?刻面不能被默认构造(至少我认为)......
    • @0x499602D2 new std::ctype&lt;char&gt; 调用默认构造函数
    • @0x499602D2 当您想单独获取“ja_JP”的 ctype 方面时,不涉及任何语言环境对象。
    • 所以要明确一点,当我有 locale("ja_JP") 时,此语言环境的 ctype 方面使用常规“C”classic_table?你为我解决了很多困惑,谢谢。 :)
    • @0x499602D2 是的,如果你构造locale("ja_JP"),那么它的所有方面都是 ja_JP 方面,有日语分类、整理、格式化等。这就是重点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 2012-03-23
    • 2017-12-04
    • 2018-10-12
    • 2015-03-06
    相关资源
    最近更新 更多