c++字符特性模板char_traits,到底是什么?

本文深入剖析了C++中的字符特性模板char_traits,详细解释了其内部结构和工作原理,并通过实例展示了如何使用该模板进行字符操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c++字符特性模板,到底是什么?
作为一个老程序员,也一直对它觉得很是模糊和神秘,这到底是个什么东西,需要揭开这个面纱了.
怎么揭开,相关文档看不到,就剩下看代码了. 我的环境是ubuntu20, c++库是libstdc++-9-dev

打开/usr/include/c++/9/bits/char_traits.h, 这就是char_traits 的真身了.

它分为3个部分:
第一部分是 __gnu_cxx, 占据47-213行
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
} // namespace

第2,3部分是 std 命名空间, 分成两段,共占据215-841行
namespace std _GLIBCXX_VISIBILITY(default)
{
}
就分析一下gnu 的吧,它代码比较少。说明问题为主,并最后给出一个测试.
它又分为声明部分,若干个函数实现部分,我就分析声明部分吧,它包含了几个简单的实现,
复杂的实现它放到了后面部分中,为简化把较复杂代码忽略了。
摘录下核心部分,75行,这部分代码可以和我的测试代码构成一个编译工程.

#include <bits/stl_algobase.h>
#include <bits/postypes.h>
template<typename _T>
struct _Any_Struct
{
	//定义变量别名, 只不过它限定在一个struct 结构中
	//如果去掉 template<typename _CharT> 模板限制,
	//再去掉 struct _Char_types 限制, 
	// 就是不加任何限制来重定义变量别名,那就是c了, 就看懂了,只是范围就放开了.
// 外部看等价于typedef unsigned long _Any_Struct<_T>::int_type
	typedef unsigned long   int_type; 
	typedef std::streampos  pos_type;
	typedef std::streamoff  off_type;
	typedef std::mbstate_t  state_type;
};


template<typename _T>
struct char_traits
{
	//再次重新定义变量别名,定义别名,只是为了使用时通俗化一点
	typedef _T                                    char_type;
	typedef typename _Any_Struct<_T>::int_type    int_type;
	typedef typename _Any_Struct<_T>::pos_type    pos_type;
	typedef typename _Any_Struct<_T>::off_type    off_type;
	typedef typename _Any_Struct<_T>::state_type  state_type;

	//static 是说,我这个函数是不需要this 指针的.
	//constexpr 是说, 函数是常量表达式, 在编译阶段就确定了函数形式
	//如果去掉char_traits 包装, 这跟普通的c 函数没有什么两样.
	static constexpr  void
	assign(char_type& __c1, const char_type& __c2)
		{ __c1 = __c2; }

	static constexpr bool
	eq(const char_type& __c1, const char_type& __c2)
		{ return __c1 == __c2; }

	static constexpr bool
	lt(const char_type& __c1, const char_type& __c2)
		{ return __c1 < __c2; }

	static constexpr  int
	compare(const char_type* __s1, const char_type* __s2, std::size_t __n);

	static constexpr  std::size_t
	length(const char_type* __s);

	static constexpr  const char_type*
	find(const char_type* __s, std::size_t __n, const char_type& __a);

	static constexpr char_type*
	move(char_type* __s1, const char_type* __s2, std::size_t __n);

	static constexpr char_type*
	copy(char_type* __s1, const char_type* __s2, std::size_t __n);

	static constexpr char_type*
	assign(char_type* __s, std::size_t __n, char_type __a);

	static constexpr char_type
	to_char_type(const int_type& __c)
		{ return static_cast<char_type>(__c); }

	static constexpr int_type
	to_int_type(const char_type& __c)
		{ return static_cast<int_type>(__c); }

	static constexpr bool
	eq_int_type(const int_type& __c1, const int_type& __c2)
		{ return __c1 == __c2; }

	static constexpr int_type
	eof()
		{ return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }

	static constexpr int_type
	not_eof(const int_type& __c)
		{ return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
};

放上我的测试代码:

#include <stdio.h>
#include "char_traits.h"
int main()
{
	char c1='a';
	char c2='b';
	char_traits<char>::assign(c1,c2); //类型charT给的是char, 所以参数就可以用char类型变量了
	printf("now c1 is:%c\n",c1);
	bool ret=char_traits<char>::eq(c1,c2);
	printf("eq ret:%d\n",ret);
// 测试代码没有实现比较函数,如果想测试可以继续copy加入其对应实现部分
//	int iret=char_traits<char>::compare((const char*)c1,(const char *)c2,sizeof(char));
//	printf("compare iret:%d\n",iret);
	return 0;
}

小结:
char_traits: 字符属性类. 处理的是字符类型
在它的命名空间下,实现了以下基本操作函数,
字符赋值,相等判别,小于判别,比较函数,长度,查找,移动,拷贝,类型变换,文件尾字符判别等。

如果忽略命名空间,再固定上变量类型,那它就是纯c 函数.
字符属性类也没有什么神秘性了,它是字符操作的一组函数,放到了char_traits 结构下.
你还可以扩展一些你想要的函数.

char_traits 可以认为它啥都不是,就是一个限定字符,就是限制到或精确到某某结构下的某某变量.

char_traits<char> 是说我后面操作的数据类型是char 类型. 习惯了就好了,计算机需要严格定义.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值