什么是std::mbstate_t?

3
我正在创建一个自定义的语言环境,通过继承 std::codecvt 实现。大多数要实现的方法都很直接,除了这个 std::mbstate_t。在我的编译器 vs2010 中,它被声明为一个 int。但是,谷歌告诉我它是一个 POD 类型,有时是联合体(我不知道是哪些)或者结构体(同样我也找不到)。据我所知,std::mbstate_t 是部分转换的占位符。而且,当 std::codecvt::on_out() 需要更多空间来写输出时,我认为它会发挥作用,这反过来又会调用 std::codecvt::do_unshift()。如果我的假设有误,请纠正我。
我已经阅读了关于存储指针的另一篇文章,但该文章没有足够的答案。我也阅读了这个例子,它假设它是一个32位类型,尽管标准规定int不少于16位。
我的问题是:我可以安全地在std::mbstate_t中存储什么?我可以安全地将其替换为另一种类型吗?上面的文章建议替换它,但下面的评论则表示相反。
1个回答

3
如果你想认真地处理这些问题,我认为与此相关的书籍是Langer和Kreft的C++IOStreams和Locales。 现在回到你的问题上,在正常情况下,mbstate_t用于保存转换的状态。 通常,您会将此存储在转换facet中,但由于facets是不可变的,因此您需要在外部进行存储。 在实践中,当您需要多个字节序列来确定相应字符时,这种情况就会发生,例如Linux manpage中的mbsinit()给出了ISO-2022和UTF-7作为此类编码的示例。 请注意,这不会影响UTF-8,其中单个Unicode代码点始终由一系列字节编码,并且不会在其之前或之后影响结果。 这也没有处理UTF-8的部分序列,do_in()返回partial。

现在,您可以在mbstate_t中存储什么? 由于实际类型未定义并且操作它的函数数量非常有限,因此起初您无法对其进行任何操作。 然而,其他任何东西都不会对该状态进行任何操作,因此您可以对其进行一些丑陋的黑客操作。 这可能需要根据标准库进行一些#ifdef,但然后您可以简单地(滥用)它是POD(int和union也是POD)的事实来存储几乎任何类型的POD,只要它不大于mbstate_t。 这不会使您赢得美丽奖,代码也不会自动在任何系统上工作,但我认为在这种情况下是不可避免的,并且移植工作也很有限。

最后,您可以替换它吗? 该类型是std :: char_traits的一部分,而std :: char_traits又影响所有字符串和流,因此您需要在整个程序中替换它们或进行转换。 此外,如果现在创建一个新的char_traits类,则仍然无法轻松地实例化例如basic_string,因为没有保证通用的basic_string模板甚至存在,只需要存在两个特殊化的char和wchar_t(以及一些更多的C++11)。 流也是如此。 简而言之,不能替换mbstate_t。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接