条款2~3:GotW#29 不区分大小写的string

编写一个与标准的std::string类完全相同ci_string类,但是它与通常提供的扩展函数stricmp一样是不区分大小写的。ci_string应用能够如下使用:

ci_string s("AbCde");
//不区分大小

assert(s == "abcde");
assert(s == "ABCDE");

assert(strcmp(s.c_str(),"AbCdE") == 0);
assert(strcmp(s.c_str(),"abcde") == 0);

C++标准库中,string的头文件声明如下:

typedef basic_string<char> string;

template<class charT,
		 class traits = char_traits<charT>,
		 class Allocator = allocator<charT> >
class basic_string;

函数中,char_traits定义了字符串之间的相互作用和比较的方式;char_traits模板提供了名为eq()和lt()的字符串比较函数,提供了compare()和find()函数来比较和查找字符串,如果我们想这些函数有不同的行为表现,所要做的只是提供一个不同的char_traits模板:

struct ci_char_traits : public char_traits<char>
{
	static bool eq(char c1,char c2)
	{
		return toupper(c1) == toupper(c2);
	}

	static bool lt(char c1,char c2)
	{
		return toupper(c1) < toupper(c2);
	}
	
	static int compare(const char* s1,const char* s2,
					   size_t n)
	{
		return memicmp(s1,s2,n);//linux可以使用strncasecmp替代
	}
	
	static const char* find(const char* s,int n,char a)
	{
		while(n-- > 0 && toupper(*s) != toupper(a))
		{
			++s;
		}
		return s;
	}
}

typedef basic_string<char,ci_char_traits> ci_string;

我们重新定义了一个ci_string,它的操作非常像标准的string,只是使用了ci_char_traits替代了char_traits<char>以使用特别的规则。

这次GotW揭示了basic_string模板工作的原理以及实现使用上的灵活性。

问题:

1.使用这种方式从char_traits<char>继承ci_char_traits是安全的么?

继承是安全的,但是这里不能多态的使用ci_char_traits。

2.为什么如下的代码编译失败呢(由于C++的改进,现在可以编译通过,并正常运行。)?

ci_string s = "abc";
cout << s << endl;

因为在C++标准库中,base_string的operator<<声明如下(C++标准中已将base_ostream<charT,traits>& os改为“ostream&”,所以没问题了):

template<class charT,char traits,class Allocator>
basic_ostream<charT,traits>&
operator <<(basic_ostream<charT,traits>& os,
			const basic_string<charT,traits,Allocator& str>);

有两个解决方法:定义ci_string自己的输入/输出流函数,或使用".c_str()":

cout << s.c_str() << endl;

3.当在标准string对象和ci_string对象间使用其他的(如+,+=,=)时,例如:

sting a = "aaa";
ci_string b = "bbb";
string c = a + b;

解决方法还是定义自己的这些操作函数,或者添加使用“.c_str()”:

cout << c = a + b.c_str();

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值