c++ char_traits模板类的实现!!!

深入解析C++字符特性模板char_traits:从源码到实战应用 本文深入解析C++标准库中的字符特性模板char_traits,从源码结构剖析其作为“字符操作工具箱”的设计原理。通过对比、查找、拷贝等核心成员函数的详解与实战示例,展示其如何为std::basic_string提供可定制的底层操作。文章重点演示了如何通过自定义char_traits实现大小写不敏感字符串,并探讨了其在模板元编程与支持自定义字符类型中的关键角色,帮助开发者深入理解C++ Traits编程技法与标准库的泛型设计思想。 阅读详情

本人写过与此相关的两篇博客,一个是<cstring>头文件的实现,另一个是<cwchar>的实现,这里的char_traits模板类在此基础上实现。

为了方便,将源代码一起封装于名字空间mystd里。

代码如下!!!



// 此文件命名为   "char_traits.h"

// vs2012 调试通过
#pragma once 
#ifndef MYSTD_CHAR_TRAITS_H
#define MYSTD_CHAR_TRAITS_H


#include<cstddef> // std::size_t 
#include<cassert>

#pragma push_macro("EOF")
#undef EOF 
#define EOF (-1)

#pragma push_macro("WEOF")
#undef WEOF 
#define WEOF (unsigned short)(0xFFFF)

#define MYSTD_BEGIN namespace mystd{
#define MYSTD_END  }



#ifdef __cplusplus



MYSTD_BEGIN  //cstring.h
	typedef std::size_t size_type;
	typedef unsigned char UCHAR;
	// C语言版本,void * memchr(const void *,int,size_type); 
	inline const void* memchr(const void *pointer,int val, size_type num)
	{
		assert(pointer != 0);
		UCHAR *ptr = (UCHAR*)pointer;
	    for(size_type i = 0; i < num; ++i)
		{
			if(*ptr == val)
				break;
			++ptr;
		}
		return ptr;
	}
    inline void* memchr(void *pointer, int val,size_type num) //c++重载
	{
		assert(pointer != 0);
		return (void*)mystd::memchr((const void*)pointer,val,num); // 转调
	}
	inline size_type strlen(const char *str)
	{
		assert(str != 0);
		size_type count = 0;
		while(*str++)
			++count;
		return count;
	}

	inline void* memmove(void *destination,const void *source, size_type num)
	{ // 对于memmove函数的实现,c++之父在《c++ 程序设计语言》(十周年中文纪念版第16章开篇)
	  //就说过,此函数无法由c++语言本身达到最优实现,实际应用时还是用标准库吧!
        assert(destination != 0 && source != 0);  
		if(destination == source || num == 0)
			return destination;
		UCHAR *des = (UCHAR*)destination;  
		const UCHAR *src = (UCHAR*)source;  
		if(des < src || des >= src + num)  
		{
				while(num--)
					*des++ = *src++;
				return destination;
		}
		des += num;
		src += num;
		while(num--) // 倒序复制
			*--des = *--src;
		return destination;
	}
	inline void* memcpy(void *destination,const void *source, size_type num)
	{
		assert(destination != 0 && source != 0);
		return mystd::memmove(destination,source,num);
	}
	inline int memcmp(const void *pointer_1,const void *pointer_2,size_type num)
	{
		assert(pointer_1 != 0 && pointer_2 != 0);
		const UCHAR *ptr_1 = (UCHAR*)pointer_1;
		const UCHAR *ptr_2 = (UCHAR*)pointer_2;
		while(num-- && *ptr_1 == *ptr_2)
			++ptr_1,++ptr_2;
		if(num == size_type(-1))
			return 0;
		else
			return *ptr_1 - *ptr_2;
	}
	inline void* memset(void *pointer,int val,size_type num)
	{
		assert(pointer != 0);
		UCHAR *ptr = (UCHAR*)pointer;
		while(num--)
			*ptr++ = val;
		return pointer;
	}
	inline char* strcat(char *destination,const char *source)
	{
		assert(destination != 0 && source != 0);
		char *ptr = destination + mystd::strlen(destination);
		while(*ptr++ = *source++);
		return destination;
	}
	inline char *strncat(char *destination,const char *source,size_type num)
	{
		assert(destination != 0 && source != 0);
		char *ptr = destination + mystd::strlen(destination);
		while(num-- && *source)
			*ptr++ = *source++;
		*ptr = 0;   // null-character 复制
		return destination;
	}
	inline char *strcpy(char *destination,const char *source)
	{
		assert(destination != 0 && source != 0);
		char *des = destination;
		while(*des++ = *source++); 
		return destination; // null-character被复制
	}
	inline char *strncpy(char *destination,const char *source,size_type num)
	{
		assert(destination != 0 && source != 0);
		char *des = destination;
		while(num--)
			*des++ = *source++; 
		return destination; // null-character可能没有被复制
	}
	inline int strcmp(const char *str1,const char *str2)
	{
      assert(str1 != 0 && str2 != 0);
	  while(*str1 && *str1 == *str2)
		  ++str1, ++str2;
	  return *str1 - *str2;
	}
	inline int strncmp(const char *str1,const char *str2,size_type num)
	{
		assert(str1 != 0 && str2 != 0);
		while(num-- && *str1 && *str1 == *str2)
			++str1, ++str2;
		if(num == size_type(-1))  // 包含了num == 0的情况
			return 0;
		else
			return *str1 - *str2;
	}
	//C语言只有一个版本 char* strchr(const char *, int); 
	inline const char* strchr(const char *str,int character)
	{
		assert(str != 0);
		// 语言标准规定character 为int,这里转换一下
		const char chr = *(char*)&character;
		while(*str && *str != chr) 
			++str;
		if(*str)
			return str;
		else
			return 0;
	}
    inline char* strchr(char *str,int character) //c++重载
	{
		assert(str != 0);
		return (char*)mystd::strchr((const char*)str,character);
	}
	inline const char* strrchr(const char *str,int character)
	{ //这里的character 可能包括null-character
		assert(str != 0);
		// 语言标准规定character 为int,这里转换一下
		const char chr = *(char*)&character;
		size_type len = mystd::strlen(str);
		const char *ptr = str + len;
		if(chr == 0)
			return ptr;
		--ptr;
		while(len--)
			if(*ptr == chr)
				return ptr;
			else
				--ptr;
		return 0;  //无匹配的字符
	}
    inline char* strrchr(char *str,int character)
	{
		assert(str != 0);
		return (char*)mystd::strrchr((const char*)str,character); // 转调
	}
	//c语言版本char* strstr(const char *,const char*);
	inline const char* strstr(const char* str1,const char* str2)
	{
		assert(str1 != 0 && str2 != 0);
		size_type len_1 = mystd::strlen(str1);
		size_type len_2 = mystd::strlen(str2);
		if(len_1 < len_2) 
			return 0;
		const char *search_last = str1 + (len_1 - len_2);
		while(str1 <= search_last)
		{
			if(mystd::strncmp(str1,str2,len_2) == 0)
				return str1;
			else
				++str1;
		}
		return 0;
	}
    inline char* strstr(char *str1,const char *str2) //c++重载
	{
		assert(str1 != 0 && str2 != 0);
		return (char*)mystd::strstr((const char*)str1,str2);
	}
	inline bool is_inside(const char *str,char chr) // 辅助函数,内部使用
	{
		assert(str != 0);
		while(*str)
		{
			if(*str == chr)
				return true;
			else 
				++str;
		}
		return false;
	}
	inline size_type strspn(const char* str1,const char *str2)
	{
		assert(str1 != 0 && str2 != 0);
		size_type count = 0;
		while(*str1 && is_inside(str2,*str1))
			  ++count, ++str1;
		return count;
	}
	inline size_type strcspn(const char* str1,const char *str2)
	{
		assert(str1 != 0 && str2 != 0);
		size_type count = 0;
		while(*str1 && !is_inside(str2,*str1))
			++count, ++str1;
		return count;
	}
	// c语言版本char* strpbrk(const char *,const char *); 
	inline const char* strpbrk(const char *str1,const char *str2)
	{
		assert(str1 != 0 && str2 != 0);
		while(*str1 && !is_inside(str2,*str1))
			++str1;
		if(*str1 == 0)
			return 0;
		else
			return str1;
	}
    inline char* strpbrk(char *str1,const char *str2) //c++重载
	{
		assert(str1 != 0 && str2 != 0);
		return (char*)strpbrk((const char*)str1,str2);  //转调
	}
	inline char* strtok(char *str,const char *delim)
	{    
#ifdef _DEBUG
		static bool first_switch = false;
		if(!first_switch)
			assert(str != 0);
		assert(delim != 0);
#endif
		static char * p_location = 0;  //记录搜索起始位置
		if(str)
			p_location = str;
		char *ptr = mystd::strpbrk(p_location,delim);
		char *temp = p_location;
		if(ptr == 0) // 找不到分隔符,默认为搜索结束
		{
#ifdef _DEBUG
			first_switch = false;  // 搜索结束,first_switch置为false  
#endif
			p_location = 0;  // 搜索结束,p_location 复位
			return temp;
		}
#ifdef _DEBUG
		first_switch = true;
#endif
		*ptr = 0;
		p_location = ptr + 1; // 位置更新
		return temp;
	}
	inline size_type strxfrm(char *destination,const char *source,size_type num);
	inline int strcoll(const char *str1,const char *str2);
	inline char* strerror(int errnum);


MYSTD_END  // end of namespace mystd 


MYSTD_BEGIN   //宽字符版本
	typedef std::size_t size_type;
	typedef wchar_t char_type;
	inline size_type wcslen(const char_type* wcs)
	{
     assert(wcs != 0);
	 size_type count = 0;
	 while(*wcs++)
		 ++count;
	 return count;
	}
	inline char_type* wcscat(char_type* destination,const char_type *source)
	{
		assert(destination != 0 && source != 0);
		char_type *des = destination + mystd::wcslen(destination);
		while(*des++ = *source++);
		return destination;
	}
	inline char_type* wcsncat(char_type* destination,const char_type *source,size_type num)
	{
		assert(destination != 0 && source != 0);
		char_type *des = destination + mystd::wcslen(destination);
		while(num-- && *source)
			*des++ = *source++;
		*des = 0; 
		return destination;
	}
	inline char_type* wcscpy(char_type *destination,const char_type *source)
	{
		assert(destination != 0 && source != 0);
		char_type *des = destination;
		while(*des++ = *source++);
		return destination;
	}
	inline char_type* wcsncpy(char_type *destination,const char_type *source,size_type num)
	{
		assert(destination != 0 && source != 0);
		char_type *des = destination;
		while(num--)
			*des++ = *source++; 
		return destination; // 可能不包含null wide character 
	}
	inline int wcscmp(const char_type *wcs1,const char_type *wcs2)
	{
		assert(wcs1 != 0 && wcs2 != 0);
		while(*wcs1 && *wcs1 == *wcs2)
			++wcs1, ++wcs2;
		return *wcs1 - *wcs2;
	}
	inline int wcsncmp(const char_type *wcs1,const char_type *wcs2,size_type num)
	{
		assert(wcs1 != 0 && wcs2 != 0);
		while(num-- && *wcs1 && *wcs1 == *wcs2)
			++wcs1, ++wcs2;
		if(num == size_type(-1))  // 包含了num == 0的情况
			return 0;
		else
			return *wcs1 - *wcs2;
	}
	inline const char_type* wmemchr(const char_type* pointer,char_type val,size_type num)
	{
    	assert(pointer != 0);
		char_type *ptr = (char_type*)pointer;
	    for(size_type i = 0; i < num; ++i)
		{
			if(*ptr == val)
				break;
			++ptr;
		}
		return ptr;
	}
    inline char_type* wmemchr(char_type* pointer,char_type val,size_type num)
	{
		assert(pointer != 0);
		return (char_type*)wmemchr((const char_type*)pointer,val,num);
	}
	inline int wmemcmp(const char_type *ptr_1,const char_type *ptr_2,size_type num)
	{
		assert(ptr_1 != 0 && ptr_2 != 0);
		while(num-- && *ptr_1 == *ptr_2)
			++ptr_1, ++ptr_2;
		if(num == size_type(-1))
			return 0;
		else
			return *ptr_1 - *ptr_2;
	}
	inline char_type* wmemset(char_type *pointer,char_type val,size_type num)
	{
		assert(pointer != 0);
		char_type *ptr = pointer;
		while(num--)
			*ptr++ = val;
		return pointer;
	}
	inline char_type* wmemmove(char_type *destination,const char_type *source,size_type num)
	{
		assert(destination != 0 && source != 0); 
		if(destination == source || num == 0)
			return destination;
		char_type *des = (char_type*)destination;  
		const char_type *src = (char_type*)source;  
		if(des < src || des >= src + num)  
		{
				while(num--)
					*des++ = *src++;
				return destination;
		}
		des += num;
		src += num;
		while(num--) // 倒序复制
			*--des = *--src;
		return destination;
	}
	inline char_type* wmemcpy(char_type *destination,const char_type *source,size_type num)
	{
		assert(destination != 0 && source != 0);
		return mystd::wmemmove(destination,source,num);
	}
	inline bool w_is_inside(const char_type *wcs,char_type val) // 辅助函数,内部使用
	{
		assert(wcs != 0);
		while(*wcs)
		{
			if(*wcs == val)
				return true;
			else 
				++wcs;
		}
		return false;
	}
	inline size_type wcsspn(const char_type *wcs1,const char_type *wcs2)
	{
		assert(wcs1 != 0 && wcs2 != 0);
		size_type count = 0;
		while(*wcs1 && w_is_inside(wcs2,*wcs1))
			++count, ++wcs1;
		return count;
	}
	inline size_type wcscspn(const char_type *wcs1,const char_type *wcs2)
	{
		assert(wcs1 != 0 && wcs2 != 0);
		size_type count = 0;
		while(*wcs1 && !w_is_inside(wcs2,*wcs1))
			++count, ++wcs1;
		return count;
	}
	inline const char_type* wcsstr(const char_type *wcs1,const char_type *wcs2)
	{
		assert(wcs1 != 0 && wcs2 != 0);
		size_type len_1 = mystd::wcslen(wcs1);
		size_type len_2 = mystd::wcslen(wcs2);
		if(len_1 < len_2) 
			return 0;
		const char_type *search_last = wcs1 + (len_1 - len_2);
		while(wcs1 <= search_last)
		{
			if(mystd::wcsncmp(wcs1,wcs2,len_2) == 0)
				return wcs1;
			else
				++wcs1;
		}
		return 0;
	}
    inline char_type* wcsstr(char_type *wcs1,const char_type *wcs2)
	{
		assert(wcs1 != 0 && wcs2 != 0);
		return (char_type*)mystd::wcsstr((const char_type*)wcs1,wcs2);
	}

	inline const char_type* wcschr(const char_type *wcs,char_type val)
	{
		assert(wcs != 0);
		while(*wcs && *wcs != val)
			++wcs;
		if(*wcs)
			return wcs;
		else
			return 0;
	}
	inline char_type* wcschr(char_type *wcs,char_type val)
	{
		assert(wcs != 0);
		return (char_type*)mystd::wcschr((const char_type*)wcs,val);
	}
	inline const char_type* wcsrchr(const char_type *wcs,char_type val)
	{ // val可能为null wide character 
		assert(wcs != 0);
		size_type len = mystd::wcslen(wcs);
		const char_type *ptr = wcs + len;
		if(val == 0)
			return ptr;
		--ptr;
		while(len--)
			if(*ptr == val)
				return ptr;
			else
				--ptr;
		return 0;  //无匹配的字符
	}
	inline char_type* wcsrchr(char_type *wcs,char_type val)
	{  //val可能为null wide character 
		assert(wcs != 0);
		return (char_type*)mystd::wcsrchr((const char_type*)wcs,val); // 转调
	}
    
	inline const char_type* wcspbrk(const char_type *wcs1,const char_type *wcs2)
	{
		assert(wcs1 != 0 && wcs2 != 0);
		while(*wcs1 && !w_is_inside(wcs2,*wcs1))
			++wcs1;
		if(*wcs1 == 0)
			return 0;
		else
			return wcs1;
	}
	inline char_type* wcspbrk(char_type *wcs1,const char_type *wcs2)
	{
		assert(wcs1 != 0 && wcs2 != 0);
		return (char_type*)mystd::wcspbrk((const char_type*)wcs1,wcs2);
	}
	inline char_type* wcstok(char_type *wcs,const char_type *delim)
	{
#ifdef _DEBUG
		static bool first_switch = false;
		if(!first_switch)
			assert(wcs != 0);
		assert(delim != 0);
#endif
		static char_type * p_location = 0;  //记录搜索起始位置
		if(wcs)
			p_location = wcs;
		char_type *ptr = mystd::wcspbrk(p_location,delim);
		char_type *temp = p_location;
		if(ptr == 0) // 找不到分隔符,默认为搜索结束
		{
#ifdef _DEBUG
			first_switch = false;  // 搜索结束,first_switch置为false  
#endif
			p_location = 0;  // 搜索结束,p_location 复位
			return temp;
		}
#ifdef _DEBUG
		first_switch = true;
#endif
		*ptr = 0;
		p_location = ptr + 1; // 位置更新
		return temp;
	}
	inline size_type wcsxfrm(char_type *destination,const char_type *source,size_type num);
     

MYSTD_END






MYSTD_BEGIN   
	typedef unsigned short wint_t;
	template<class charT>
	struct char_traits{
		typedef std::size_t size_type;
	};

	template<>  // char特化
	struct char_traits<char>{
		typedef int int_type;
		typedef char char_type;
	public:
		static size_type length(const char_type *str) throw()
		{
			assert(str != 0);
			return mystd::strlen(str);
		}

       static void assign(char_type& chr,const char_type& val) throw()
	   {
		   chr = val;
	   }
       static char_type assign(char_type *ptr,size_type num,char_type chr) throw()
	   {
		   assert(ptr != 0);
		   mystd::memset(ptr,chr,num);
		   return chr;
	   }
	   static int compare(const char_type *str1,const char_type *str2,size_type num) throw()
	   {
		   assert(str1 != 0 && str2 != 0);
		   return mystd::strncmp(str1,str2,num); // 注意C风格字符串
	   }
	   static char_type* move(char_type *des,const char_type *src,size_type num) throw()
	   {
		   assert(des != 0 && src != 0);
#ifdef _DEBUG
		   return (char_type*)mystd::memmove(des,src,num);
#else
		   return (char_type*)std::memmove(des,src,num); // 标准库版本效率更高
#endif
	   }
	   static char_type* copy(char_type *des,const char_type *src,size_type num) throw()
	   {
		   assert(des != 0 && src != 0);
#ifdef _DEBUG
		   return (char_type*)mystd::memcpy(des,src,num);
#else
           return (char_type*)std::memcpy(des,src,num); // 标准库版本效率更高
#endif
	   }
	   static bool eq(const char_type& chr_1,const char_type& chr_2)
	   {
		   return chr_1 == chr_2;
	   }
	   static const char_type* find(const char_type* ptr,size_t num,const char_type& chr)
	   {
		   assert(ptr != 0);
		   while(num-- && *ptr != chr)
			   ++ptr;
		   if(*ptr == chr && num != size_type(-1)) // 不依赖于null character 
			   return ptr;
		   else
			   return 0;
	   }
	   static char_type to_char_type(const int_type& chr) throw()
	   {
		   assert(chr < 0xFF);
		   return *(char_type*)&chr;
	   }
	   static int_type to_int_type(const char_type& chr) throw()
	   {
		   return static_cast<char_type>(chr);
	   }
	   static int_type eof() throw()
	   {
		   return EOF;
	   }
	};

	template<>  // 宽字符版本
	struct char_traits<wchar_t>{
		typedef wint_t int_type;
		typedef wchar_t char_type;
	public:
		static size_type length(const char_type *wcs) throw()
		{
			return mystd::wcslen(wcs);
		}
       static void assign(char_type& wc,const char_type& val) throw()
	   {
		   wc = val;
	   }
       static char_type assign(char_type *ptr,size_type num,char_type wc) throw()
	   {
		   assert(ptr != 0);
		   while(num--)
			   *ptr++ = wc;
		   return wc;
	   }
	   static int compare(const char_type *wcs1,const char_type *wcs2,size_type num) throw()
	   {
		   assert(wcs1 != 0 && wcs2 != 0);
		   return mystd::wcsncmp(wcs1,wcs2,num);
	   }
	   static char_type* move(char_type *des,const char_type *src,size_type num) throw()
	   {
		   assert(des != 0 && src != 0);
#ifdef _DEBUG
		   return (char_type*)mystd::wmemmove(des,src,num);
#else
		   return (char_type*)std::wmemmove(des,src,num);  // 标准库版本效率更高
#endif
	   }
	   static char_type* copy(char_type *des,const char_type *src,size_type num) throw()
	   {
		   assert(des != 0 && src != 0);
#ifdef _DEBUG
		   return (char_type*)mystd::wmemcpy(des,src,num);
#else
		   return (char_type*)std::wmemcpy(des,src,num);  // 标准库版本效率更高
#endif
	   }
	   static bool eq(const char_type& wc_1,const char_type& wc_2)
	   {
		   return wc_1 == wc_2;
	   }
	   static const char_type* find(const char_type* ptr,size_t num,const char_type& wc)
	   {
		   assert(ptr != 0);
		   while(*ptr && num-- && *ptr != wc)
			   ++ptr;
		   if(*ptr == wc)
			   return ptr;
		   else
			   return 0;
	   }
	   static char_type to_char_type(const int_type& wc) throw()
	   {
		   assert(wc < 0xFFFF);
		   return wc;
	   }
	   static int_type to_int_type(const char_type& wc) throw()
	   {
		   assert(wc < 0xFFFF);
		   return wc;
	   }
	   static int_type eof() throw()
	   {
		   return WEOF;
	   }
	};

MYSTD_END // end of namespace mystd 
#endif // __cplusplus 
#pragma pop_macro("WEOF")
#pragma pop_macro("EOF") 
#endif // MYSTD_CHAR_TRAITS_H


希望高手批评指正!!!








C++ char_traits实战指南:如何自定义字符特性类优化字符串处理 本文深入探讨了C++中char_traits模板类的实战应用,指导开发者如何通过自定义字符特性类来优化字符串处理。文章以不区分大小写比较、处理特殊编码等实际场景为例,详细解析了自定义char_traits的实现方法、核心成员函数以及跨平台兼容性考量,为处理复杂字符串需求提供了灵活高效的解决方案。 阅读详情

相关推荐

C++(03):string中的char_traits

string实际上模板类basic_string的实例重命名 typedef basic_string<char> string; 而模板类basic_string的定义如下: template < class charT, class traits = char_traits<charT>, // basic_string::traits_type class Alloc = al

风静如云的博客 954

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

小结: char_traits: 字符属性类. 处理的是字符类型 在它的命名空间下,实现了以下基本操作函数, 字符赋值,相等判别,小于判别,比较函数,长度,查找,移动,拷贝,类型变换,文件尾字符判别等。 如果忽略命名空间,再固定上变量类型,那它就是纯c 函数. 字符属性类也没有什么神秘性了,它是字符操作的一组函数,放到了char_traits 结构下. 你还可以扩展一些你想要的函数.

hjjdebug的专栏 2974

SolidWorks的GB库(钢型材库,包括铝型材、铝管等结构)安装及使用教程(生成铝型材为例)

1、GB库的下载 2、GB库的安装教程 3、GB库的使用教程

树下等苹果的博客 12万+

basic_string的各个模板参数,尤其是char_traits到底是什么

但是,明明是函数的集合,叫它XXX_traits,是不是有点让人迷惑,就因为它有一堆typedef?打开char_traits的定义,发现它就是一个都是操作字符串static函数的结构体。每次看到都觉得不明所以:第一个char还能理解,第二个char_traits是什么?其实源码之下,了无秘密。

tumu_C的博客 533

visual studio 2017编译Triangle库遇到的问题和解决办法

这段时间因为一个项目需要使用到Triangle这个三角剖分工具,需要在windows环境下进行对源码编译,中间踩了很多坑,特此记录下。 1、下载 下载链接是下边这个,需要翻墙 http://www.cs.cmu.edu/~quake/triangle.html 2、编译。。超。。。级。。。麻。。。烦。。。 在ubutu下安装一切顺利,完全没遇到什么麻烦,但是换到windows下就麻烦不断...

csubai07的博客 2438

卫星图像检测,分割,跟踪,超分辨率,数据集调研,以及论文笔记

目标检测,针对物体有很多类如桥,烟囱,罐子等,有静态图像下的检测,也就是图像源头多来自谷歌地图,但是前后帧没有任何联系,并且谷歌地图相对来说比较清楚,难度小一点,也有粗粒度以及较细粒度的检测,然后卫星视频的数据集较少,则可以通过前后帧的联系来辅助检测,并且卫星帧基本上只对车,船,飞机,火车进行检测,没有进行细粒度的检测即将车辆分类为卡车,皮卡,小轿车,但是关船,则可以分类为货船以及军舰,因为目前的卫星视频中小车实在太少了,难以进行更细粒度的检测。luojia 三号卫星。

zhangzhao147的博客 4706

char_traits

c++标准库中,有一个string,这个相信大家都知道,其实它是一个basic_string的一个typedef,其实在msdn这些地方,查string查不到什么太多东西,需要了解内部接口,得查basic_string 至于char_traits,是base_string的一个模板参数,它主要负责关于字符的属性和方法,譬如 eq、lt、compare、find 这些,比较字符大小,查找字符

sssxueren的专栏 4900

Verilog实战:手把手教你实现IEEE 754单精度浮点乘法器(附完整代码)

本文详细介绍了如何使用Verilog实现IEEE 754单精度浮点乘法器,包括标准解析、架构设计、Verilog代码实现及优化技巧。通过两级流水线设计,平衡性能与面积,适用于数字信号处理、AI加速器等高性能计算场景。

weixin_33724046的博客 314

C++的Char traits模板类

Char_traits 头文件Char_traits.h // Generic char_traits class.  Note that this class is provided only//  as a base for explicit specialization; it is unlikely to be useful//  as is for any p

linweixuan的专栏 4111

MicroBlaze系列教程(5):AXI_UART16550的使用

axi-uart16550是Xilinx的一款串口IP核,支持配置成16450或16550模式,16550和16450是指的早期电脑主板上的串口芯片型号,16550相比于16450多了FIFO,现在已经很少使用。相比于,16550支持1或2位停止位,包括uartlite所有的功能,而且支持在SDK中灵活对波特率、数据、校验方式进行配置。与uartlite不同的是,不能单独指定发送中断和接收中断函数,只有一个中断函数,通过event参数来区分当前是发送或接收中断。

whik1194的博客 4540

Deepseek Engram 论文全面解读

以下是对 DeepSeek 与北京大学于联合发布的论文《》(简称Engram 论文)的。

lpfasd123的博客 354

char_traits struct 初步学习

在学习文件读取时碰到文件尾字符 EOF 的问题,顺藤摸瓜找到 char_traits msdn 上关于 EOF 的说明,就一句话: Returns the end-of-file (EOF) character. 在注意中提到一句: A value that represents end of file (such as EOF or WEOF). 意思是 EOF 表示的是文

nothinglefttosay的专栏 1431

【Power Compiler手册】4.saif文件

功耗计算的准确性取决于切换活动数据的准确性。这些数据是通过使用RTL仿真或门级仿真生成的,并存储在SAIF文件中。在执行功耗优化和分析之前,应该使用SAIF文件来反标设计对象上的切换活动信息。SAIF是由Synopsys支持的ASCII格式,用于促进不同Synopsys工具之间的信息交换(参见IEEE 1801标准,附录J)。使用`read_saif`命令读取SAIF文件,使用`write_saif`命令写出SAIF文件。有关更多信息,请参见`read_saif`和`write_saif`命令的手册页。

QRBQ 2186

从char_traits.h源码看STL设计哲学:为什么C++字符串操作需要特性模板?

本文通过深入剖析char_traits.h源码,揭示了C++ STL中特性模板(Traits)的设计哲学。文章解释了char_traits如何作为连接basic_string、iostream等组件的“粘合剂”,通过将字符操作细节抽象化,实现了算法与数据类型的分离,从而支持多种字符类型和自定义比较规则,体现了C++零开销抽象和编译期多态的强大威力。

docker7nomad的博客 593

手把手教你学AI GPU的UMD驱动软件开发专栏简介

通过本专栏的学习,您将掌握UMD的核心概念、开发环境搭建、API实现、内存管理和同步技术,以及在实际AI场景中的应用。通过本专栏的学习,您将不仅掌握UMD驱动开发的核心技术,还将能够将这些技术应用到实际的AI应用场景中,为您的AI应用提供更高效的硬件加速支持。无论您是想开发自己的AI加速框架,还是希望深入理解现有AI加速库的工作原理,本专栏都将为您提供宝贵的知识和实践经验。:本专栏不仅讲解UMD驱动的核心概念,还通过精心设计的实战案例,引导您从零开始构建UMD驱动,真正掌握AI GPU驱动开发的技能。

MHD0815的博客 113

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C++ traits技术

1、技术的发明是为了某个问题,traits也是一样。考虑下面的需求。2、对两个变量相加,为了通用,使用模板方法,实现编译时多态。如下:template &lt;typename T&gt;T Add(T a,T b){ //...}3、对于int,double实现是一样的,直接相加就行了。但是对于char*,我们期望内容相加,返回一个新的指针。传统的解决办法使用方法过载,如下:int Add...

weixin_34242509的博客 293

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

C++字符特性模板char_traits实战:手把手教你自定义字符串比较规则

本文深入解析C++字符特性模板char_traits的实战应用,手把手教你如何自定义字符串比较规则。通过实现大小写不敏感的字符串比较案例,展示char_traits在字符串处理中的强大灵活性,帮助开发者掌握高级字符串操作技巧,提升代码的可扩展性和复用性。

vodka的博客 355

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C++设计新思维的traits和policy

http://blog.youkuaiyun.com/zhoudaxia/article/details/4486487 这篇博客讲得挺清楚的,本来想自己写写看总结下的,不过看了下这个文章已经写得很清楚了,倒没有必要了,总得来说,要了解traits和policy,需要了解下面这三个点 1.什么是特化,什么是偏特化 顾名思义,特化就是针对一些特殊的类型进行变化,毕竟C++的模板是什么类型都能放进...

268

大小写不敏感的字符串类(类模板char_traits的应用)

分析:        对于两个string对象的比较,归根结底将会调用模板参数traits中的字符比较函数,正是这些字符比较函数确定了两个字符串的比较规则。类string使用标准库中定义的char_traits&lt;char&gt;作为模板参数traits来实例化basic_string.由于char_traits&lt;char&gt;采用大小写敏感的规则来比较,因此类string也会采用大...

Lawrence_121 1973

提升 C++ std::string 操作效率:善用 pop_back()

pop_back() 函数是用于删除 std::string 对象的最后一个字符,实现很高效,本质上就是把要删除的最后一个字符置为null结束符,也就是置为: \0。

程序员小坤的博客 2002

字符特性char_traits定义,及其特化版本char_traits<char>,char_traits<wchar_t>

// iosfwd standard header #if _MSC_VER > 1000 #pragma once #endif #ifndef _IOSFWD_ #define _IOSFWD_ #include #include #include #inc

xudacheng06的专栏 3040

泛型编程之特性(traits)

  特性(traits):对于某种可能会出错的返回值型别(Return Type),利用类模版进行部分特例化。其思想类似设计模式。     我们只能部分特例化类模板,而不能部分特例化函数模版。——《C++ Primer(5th)》 P628 part 1.实现 Sigma 函数   功能:将一段范围内的元素求累加和。   1. 错误的代码实例: template <ty...

weixin_30632089的博客 154
上一篇: 关于WM_MOUSEHOVER和WM_MOUSELEAVE消息的用法以及按钮的变色问题!
下一篇: c++ string类的完整实现!!!
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值