问题是我不明白为什么这些应该分开。为什么不使用一个类,比如CharType,它将同时包含字符特征和字符类型的逻辑。我的意思是替换它:
template <class _Elem, class _Traits = char_traits<_Elem>, class _Alloc = allocator<_Elem>>
class basic_string { /*...*/ };
与:
template <class ExtendedTraits, class _Alloc = allocator<_Elem>>
class basic_string { /*...*/ };
其中ExtendedTraits是前面提到的_Elem和_Traits的组合,可能看起来像这样:
template<_CharType> //all the necessary template parameters
class extended_traits
{
public:
using value_type = _CharType;
private:
_CharType _elem;
public:
//... all methods, that used to be in char_traits but now non-static and accepting one parameter
};
我尝试了两种方法,两种方法都有效,但可能有一些问题我仍然没有注意到。
我认为将字符类型与Traits
对象分开更有意义。Traits
是用于字符比较之类的附加类,它本质上不同于字符类型。你的方法可以工作,但是等效的方法就像是将两个完全不同的函数组合成同一个函数。
字符串使用的字符类型也更明显。例如:
typedef string basic_string<char>;
比
明显得多typedef string basic_char<extended_traits<char>, ...>;
,因为有一个额外的嵌套级别和更多的字符等等。
在一天结束时,我们不关心Traits
是什么,我们关心字符串是什么字符类型。Traits
用于内部操作,是要抽象出来的;因此,它远离字符类型,这意味着更明显,因为它表明字符串可以包含什么类型的值。
至少,这是我对事情的看法。
此外,std::basic_string
有更多的模板实参不一定是件坏事,特别是因为只有一个模板实参真正需要为其定义形参——其他模板都给出了默认类型。我不经常需要定义自己的Traits
类。但是,如果我想用自定义字符或类似的东西定义我自己的单独的字符串类,我必须为它定义一个Traits
类,即使我已经编写了赋值操作符和比较操作符以及其他所有内容。那将特别令人恼火。