什么是std :: mbstate_t?

时间:2013-07-09 04:16:01

标签: c++ templates stl locale

我是通过从std::codecvt派生来创建自定义区域设置的。除了这个std::mbstate_t之外,我应该实现的大多数方法都非常简单。在我的编译器vs2010上,它被声明为int。但是,谷歌告诉我这是一个POD类型,它有时是一个联盟(我不知道)或结构(再次我找不到它)。

据我了解,std::mbstate_t是部分转换的占位符。并且,我认为,当std::codecvt::on_out()需要更多空间来编写输出时,它会发挥作用,而后者又会调用std::codecvt::do_unshift()。如果我的假设是错误的,请纠正我。

我已经阅读过有关存储指针的another post,但帖子没有足够的答案。我还读过this example,它假定它是32位类型,尽管标准规定int不小于16位。

我的问题。我可以安全地存储在std :: mbstate_t中吗?我可以安全地用其他类型替换它吗?上述帖子的答案建议更换它,但以下评论则另有说法。

1 个答案:

答案 0 :(得分:2)

我认为关于这些事情的/本书是C ++ IOStreams和Langers和Kreft的Locales,如果你真的想弄乱这些东西,试着抓住副本。现在,回到你的问题,mbstate_t用于保持转换的状态。通常,您会将其存储在转换构面内,但由于构面是不可变的,因此您需要将其存储在外部。在实践中,当您需要多个字节序列来确定相应字符时使用,mbsinit()的Linux联机帮助页提供了ISO-2022和UTF-7作为此类编码的示例。请注意,这不会影响UTF-8,其中单个Unicode代码点始终由一系列字节编码,并且在影响结果之前或之后没有任何内容。部分UTF-8序列也不会被处理,do_in()会返回partial

现在,您可以在mbstate_t存储什么?由于实际类型是未定义的,并且操作它的函数数量非常有限,因此您最初无法使用它。但是,这个状态也没有任何其他功能,所以你可以做一些丑陋的黑客攻击。这可能需要一些#ifdef,具体取决于标准库,但您可以简单地(ab)使用它是POD(整数和联合也是POD)的事实来存储几乎任何类型的不大的POD 。这不会为你赢得美观价格,而且代码不会自动在任何系统上运行,但我认为在这种情况下它是不可避免的,移植工作也是有限的。

最后,你能替换它吗?此类型是std::char_traits的一部分,它反过来影响所有字符串和流,因此您需要在整个程序中进行替换或转换。此外,如果您现在创建一个新的char_traits类,您仍然无法轻松实例化,例如basic_string使用它,因为无法保证一般的basic_string模板存在,只需要charwchar_t的两个特化(以及C ++ 11的一些特殊化) )存在。同样适合溪流。简而言之,没有你不能取代mbstate_t。