首先,C++不需要额外的字符串类。可能已经有数百或数千个已经开发出来的太多的字符串类,而且你的情况也不会改善。除非你完全是为了你的熏陶而做这件事,否则你应该考虑漫长而艰难,然后决定不写一个新的。
可以使用std::basic_string<char>
保持UTF-8代码单元序列,std::basic_string<char16_t>
保持UTF-16代码单元序列,std::basic_string<char32_t>
保持UTF-32代码单元序列等C++甚至提供了这些类型的短,方便的名称: string
,u16string
和u32string
。 basic_string
已经通过提供用于复制,比较和获取字符串长度的成员函数解决了您在此处提出的问题,该字符串适用于您对其进行模板化的任何代码单元。
我想不出有什么好的理由,因为新代码并没有与遗留代码进行交互,而是使用其他任何东西作为字符串的规范存储类型。即使你使用其他的遗留代码进行交互,如果该接口的表面面积不大,你应该仍然可以使用其中一种标准类型,而不是其他任何东西,当然如果你使用遗留代码无论如何,你都会使用这种遗留类型,而不是编写自己的新类型。
虽这么说,你不能strcmp
,strcpy
,并strlen
您的模板字符串类型使用的原因是,他们都在空终止字节序列进行操作。如果您的代码单元大于一个字节,则可能有字节在实际终止空值代码单元(假设您根本不应该使用空终止)之前为零。考虑字符串“Hello”的UTF-16表示字节(在一个小端机器上)。
48 00 65 00 6c 00 6c 00 6f 00
由于UTF-16使用16个编码单元,字符 'H' 最终存储为两个字节48 00
。通过假定第一个空字节为结尾来操作上述字节序列的函数将假定第一个字符的后半部分标记整个字符串的结尾。这显然是行不通的。
因此,strcmp
,strcpy
和strlen
都是可以更一般地实现的算法的专用版本。由于它们只能与字节序列一起工作,并且您需要使用代码单元序列,其中代码单元可能大于一个字节,因此您需要使用可以与任何代码单元一起使用的通用算法。标准库提供了许多通用算法可供您使用。这里是我的建议来取代这些str*
函数。
strcmp
比较两个代码单元序列,如果两个序列相等,则返回0;如果第一个按字典顺序小于第二个,则返回正数;否则返回负数。标准库包含通用算法lexicographical_compare
,它的功能几乎相同,只是如果第一个序列按字典顺序小于第二个序列,否则返回true,否则返回false。
strcpy
复制一系列代码单元。您可以使用标准库的copy
算法。
strlen
需要一个指向代码单元的指针并在发现空值之前计算代码单元的数量。如果你需要这个函数,而不是只告诉你字符串中代码单元数量的函数,你可以通过传递空值作为找到的值来使用算法find
来实现它。如果您想要查找序列的实际长度,那么您的课程应提供一个size
方法,该方法可直接访问您的课程在内部使用的任何方法来存储该尺寸。
与str*
函数不同,我建议的算法需要两个迭代器来划分代码单元序列;一个指向序列中的第一个元素,另一个指向序列最后一个元素之后的位置。 str*
函数只需要一个指向第一个元素的指针,然后假设该序列一直持续到它找到的第一个零值代码单元为止。当你实现你自己的模板化字符串类时,最好远离显式的空终止约定,并且只提供一个为你的字符串提供正确端点的方法。
头部被命名为'algorithm',而不是'algorithm.h'。另外,如果你做了很多C++编程,熟悉标准库会很有帮助,所以你不必问什么是可用的,所以你会更容易识别任何随机的情况,在这种情况下库算法是完美的。我看到很多代码是不应该写的,但作者并不知道标准库有一个算法。 http://en.cppreference.com/w/cpp/algorithm – bames53 2011-12-31 09:32:58