杰表技术论坛 's Archiver

admin 发表于 2018-7-6 18:48

c++ type traits 是什么?看stl源码,一堆 traits .

我想实现一个类,这个类具有std::string的功能,但 find,  ==等操作,需要大小写无关的?
我们使用类继承实现,看如何做到?代码如下:
// 定义大小写不敏感的string类
class istring :public std::string
{
public:
// 必须定义初始化构造函数,否则,istring x = "abc";非法
istring(const char * str) :std::string(str)
{
}
// 重载新方法
size_type find(const istring& _Right, size_type _Off = 0) const _NOEXCEPT
{
std::string this_str= this->c_str();
std::transform(this_str.begin(), this_str.end(), this_str.begin(), ::tolower);
std::string that_str = _Right.c_str();
std::transform(that_str.begin(), that_str.end(), that_str.begin(), ::tolower);
return this_str.find(that_str, _Off);
}
};
// 重载全局==操作
bool operator==(const istring & _Left, const istring & _Right)
{
return (stricmp(_Left.c_str(), _Right.c_str()) == 0);
}
int main(int argc, char* argv[])
{
istring x = "abc";
istring y = "Abc";
bool b = x == y;
auto f = x.find(y);
return 0;
}
这样实现,有几个问题:
1.因为构造函数不能自动继承,所以想要什么形式的初始化,都必须重新写一遍
2.要实现的 ==,find 方法,需要在全局或者类内,都重载一遍
3.如果想实现,rfind,那必须再重载一次这个方法,考虑到大小写不敏感的地方,很多,如何是好? 答案是用 basic_string的参数类

模板版本:
// 从默认的 std::char_traits 中继承一个
struct my_char_traits : std::char_traits<char>
{
// 重载 compare 方法
static int compare(const _Elem *_First1, const _Elem *_First2,size_t _Count)
{
return (_Count == 0 ? 0:stricmp(_First1, _First2));
}
};
int main(int argc, char* argv[])
{
// 方便使用 typedef 一下
typedef std::basic_string<char, my_char_traits> istring;
istring x = "abc";
istring y = "Abc";
bool b = x == y;
auto f = x.find(y);
return 0;
}

这个版本,要简洁很多:
1.构造函数全部可用,
2.只需要重载 char_traits的 compare方法,所有大小写对比的方法,自动生效,==,find,rfind,等,因为这些方法,最终都会调用 my_char_traits::compare方法

[b]traits是什么?traits 就是把类的部分特征,接管过来的类[/b],想让类具有不同的特征,就改变traits类,就行了
就好比:
template<typename 管家婆_traits>
class 人
{
int 有多少钱()
{
    return 管家波_traits::有多少钱()
}
}

人<老婆_traits> 程序员;// 程序员有多少钱,问老婆 traits
人<小三_traits> 贪官; // 贪官有多少钱,得问小三 traits

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.