【发布时间】:2010-11-17 13:55:18
【问题描述】:
由于std::string 实际上是模板类的typedef,我该如何覆盖它?我想制作一个 UTF-8 std::string,它会返回正确的长度等等。
【问题讨论】:
标签: c++ unicode utf-8 character-encoding
由于std::string 实际上是模板类的typedef,我该如何覆盖它?我想制作一个 UTF-8 std::string,它会返回正确的长度等等。
【问题讨论】:
标签: c++ unicode utf-8 character-encoding
如果您必须定义自己的字符串类型,那么不要从std::string 继承,而是定义自己的Character Traits 类并执行类似的操作
typedef std::basic_string<unsigned char, utf8_traits> utf8string;
【讨论】:
std::string 是 typedef 是有原因的,就是这样。
basic_string 来处理 UTF-8 序列。每当你试图操纵它时,弊大于利。
state_type,要么将它们打包为 UTF-32 并在边界处转换。无论哪种方式,工作量都很大,但它保留了与 STL 算法的兼容性。
不要从字符串派生
std::string,也就是说,基本上整个 basic_string 模板都不是为了派生而设计的。已经有数以万计的文章了。它没有任何虚函数,所以没有什么可以覆盖的。你能做的最好的事情就是隐藏一些东西。最好是使用组合/聚合!也就是说,只需在您的班级中保留一个字符串类型的成员并转发呼叫!再次,只是为了确保
不要从字符串派生
【讨论】:
std::basic_string。在这种情况下隐藏std::string 会引发char 签名问题,因为UTF-8 是一种8 位多字节编码。
basic_string 没有虚函数,那么指南 应该是:不要多态使用它。如果您正确记录了继承,则继承没有任何问题!
在 C++ 中,从标准库容器派生通常被认为是一个错误。但是,您正在寻找的功能已经实现。看看Glib::ustring。
希望这会有所帮助!
【讨论】:
你看过 ICU 吗?
typedef 只是一个方便的标签。
class foo : public bar {} ;
当 bar 是 PT 的 typedef 时工作得很好。
在这种情况下这可能不是一个好主意,但语言支持它。
【讨论】:
请确保您首先知道自己在做什么。您想从字符串对象返回的“正确长度”到底是多少?码点数?这并不总是与用户感知的字符数相对应。
不管怎样,看看utf8-cpp 库,看看从 std::string 派生的另一种方法。
【讨论】:
更好的主意:创建一个与 STL 兼容的 utf8_string 容器,而不从 std::string 继承。
【讨论】:
编写一个符合并在任何情况下都能正常工作的 unicode 实现是非常困难的。我建议您使用现有的库或实现,而不是自己滚动。例如,Windows、OSX 和 Qt 都有支持 UTF-16 和其他编码字符串的库。
【讨论】:
正如其他人已经说过的那样:不要从 std::string 派生,它不是为此而设计的。
你应该看看this article,它以如何创建不区分大小写的字符串类为例。您将看到std::basic_string 中实现的逻辑与字符类型无关,提供一些自定义char_traits 应该可以解决问题。
【讨论】: