【问题标题】:Why does std::basic_string have two separate template parameters _Elem (char type) and _Traits (char traits)?为什么 std::basic_string 有两个单独的模板参数 _Elem(char 类型)和 _Traits(char 特征)?
【发布时间】:2022-11-14 05:18:02
【问题描述】:

问题是我不明白为什么这些应该分开。为什么不使用一个类,比如 CharType,它同时包含 char 特征和 char 类型的逻辑。 我的意思是替换:

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

};

我尝试实现这两种方法,它们都有效,但可能有一些我仍然没有注意到的问题。

【问题讨论】:

  • 你更喜欢看什么,basic_string&lt;char&gt;basic_string&lt;extended_char_traits&lt;char&gt;&gt;
  • 如果要追溯basic_string 的历史和血统,几乎可以肯定我们会发现char 类型排在第一位,并且为了保持向后兼容性,添加了traits 类型作为附加的默认模板参数与现有代码。
  • char 特征可以已被假定和引用,而不是让它们成为具有默认值的参数。但是它们不能因为(比如说)需要具有不同特征的char 而变化。很可能原来的string 就是这样做的(参见 Sam 的评论)。
  • 实际上确实有匹配_ElemTraits::char_type(以及分配器的value_type
  • 我认为这是有道理的,我想要一个 char 的容器,特征和分配器只是它的补充。

标签: c++ stdstring char-traits


【解决方案1】:

我认为将字符类型与Traits 对象分开更有意义。 Traits 是用于字符比较等的附加类。如果我想定义我自己的Traits 类,我必须定义我的类,并添加一个value_type,这会很烦人,因为我必须不断地为我想要的每个自定义Traits 类重新输入它定义,特别是如果我不需要它。我可以专门为std::string 定义我的Traits 类,这样,我将只使用char 进行操作。将其分开意味着我不必定义value_type。 您的方法会起作用,但等效的方法就像将两个完全不同的函数组合成同一个函数。

字符串使用的字符类型也更加明显。例如:

typedef string basic_string<char>;

typedef string basic_char<extended_traits<char>, ...>;

因为有额外的嵌套级别和更多字符等。

归根结底,我们并不关心Traits 是什么,我们关心的是字符串是什么字符类型。 Traits 用于内部操作,意在被抽象掉;因此,它远离字符类型,这意味着更明显,因为它指示字符串可以包含哪些类型的值。

至少,这是我对事物的看法。

此外,为std::basic_string 拥有更多模板参数并不一定是坏事,尤其是因为您真正需要为其定义参数的模板参数只有一个——另一个模板具有默认类型。我并不经常需要定义自己的Traits 类。但是如果我想用自定义字符或类似的东西定义我自己的单独的字符串类,我必须为它定义一个Traits 类,即使我已经编写了赋值运算符和比较运算符以及其他所有内容。那会特别烦人。

【讨论】:

  • 实际上Trait::char_­type 必须与容器类型匹配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多