条款2:大小写不敏感的字符串--之一(2)
最后,将这些关键部分组合起来:
- typedef basic_string<char, ci_char_traits> ci_string;
上面的工作就是创建了一个ci_string类,这个类与标准库中string类(在大多数情况下,string表示的就是标准字符串)的行为非常类似,只不过在ci_string类中是通过ci_char_traits而不是char_traits<char>来实现字符之间的比较运算规则的。由于在ci_char_traits的规则中实现了大小写不敏感性,因此也就使得ci_string本身具有大小写不敏感的属性,除此之外我们并没有做任何其他改动--也就是说,我们没有对basic_string进行任何修改,就获得了一个大小写不敏感的字符串类。这就是所谓的扩展性。
3.将大小写敏感作为对象的属性是否合适?
通常,我们都是将大小写敏感作为比较函数的属性而不是对象的属性,因为这种做法在一般情况下更有用。例如,考虑以下代码:
- string a = "aaa";
- ci_string b = "aAa";
- if( a == b ) /* ... */
假定有一个函数operator==(),那么对表达式"a == b"求值的结果是真还是假?我们可以很容易得出结论:如果这两个操作数中,有任何一个操作数是大小写不敏感的,那么比较运算就应该也是大小写不敏感的。但是,如果稍微修改一下这个示例,引入basic_string的另一个模板特化类型,并进行比较:- typedef basic_string<char, yz_char_traits> yz_string;
-
- ci_string b = "aAa";
- yz_string c = "AAa";
- if( b == c ) /* ... */
现在,我们再来考虑这个问题:对表达式"a == b"求值的结果是真还是假?在上面的情况中,我想你也会认为,这两个对象之间的比较运算语义并不是显而易见的。
相反,如果将示例写成下面这样的话,比较运算的语义就会变得很清晰:
- string a = "aaa";
- string b = "aAa";
- if( stricmp( a.c_str(), b.c_str() ) == 0 ) /* ... */
- string c = "AAa";
- if( EqualUsingYZComparison( b, c ) ) /* ... */
在许多情况下,将大小写敏感性作为比较运算的属性更合适。但在实际编码过程中,我也遇到过将大小写敏感性作为对象属性的情况(尤其当大多数或者所有的比较运算都与C风格的char*字符串有关时),在这些情况中,将大小写敏感性作为对象的属性则更有用。因为这样就可以实现以一种"自然的"方式对字符串进行比较(例如,"if ( a == "text" ) ..."),而无须提醒自己每次都要使用大小写敏感的比较函数。
通过对本条款的学习,你应该能够了解basic_string模板的使用方法以及它在实际应用中的灵活性。如果希望实现与函数memicmp()和toupper()不同的比较运算,那么只需编写适合你的应用程序的字符比较运算代码,并用该代码来替换这里所给出的5个函数。