std::string和std::basic_string有什么区别?为什么两者都需要?

122

std::stringstd::basic_string有什么区别?为什么两者都需要?

5个回答

83

std::basic_string 是一个类模板,用于将字符类型组成字符串,std::string 则是该类模板针对 char 的特化版本的别名(typedef)。


26
为什么它们都是必需的? - Mohamed ElNakeep
2
那么您的意思是 std::string 是 typedef std::basic_string<char> std::string 吗? - unresolved_external
10
两年半晚了,简短回答是提供宽字符串(wstring)(Unicode,每个字符2个字节,wchar_t)支持。 - Andrew

74

std::stringstd::basic_string<T> 的实例化:

typedef std::basic_string<char> string

std::basic_string 必须针对所有类型的字符串(例如 wstring)具有类似的接口。


42
正确的术语是“专业化”。 stringbasic_string的一个专业化 - AnT stands with Russia
3
我想你可以对此进行辩论。通常情况下,“专业化”用于表示继承。模板{类|函数}通过替换模板参数来实例化。虽然有部分模板专业化,但它在这里没有被使用。 - pmr
5
将派生类称为“特化”是一种不太正式的使用“特化”的方式。在标准中几乎不会以这种方式使用“特化”这个词(我相当确定),但它广泛用于描述模板特化。模板特化的名称可以用于不强制隐式实例化的上下文中,因此,特化和实例化是分开的概念。除了模板特化(具有特定参数集的模板名称)之外,还有部分特化(仅限于类模板)和显式特化。 - CB Bailey
2
@Jerry Coffin:std::string 是一个模板特化的 typedef。使用“特化”这个词有什么误导之处? - CB Bailey
3
@Charles:这是误导性的,因为(在模板中),“特化”通常是指部分特化或显式特化,而不是typedef,后者最终会转化为简单的实例化。 - Jerry Coffin
显示剩余6条评论

32

std::stringstd::basic_string 模板的一个实例,使用了 char 类型。你需要两者结合使用,以便可以创建除了 char 之外的字符串类型,例如 std::basic_string<wchar_t> 可用于宽字符串,或者如果你想要包含32位元素的字符串,可以使用 std::basic_string<unsigned int>


3
我认为这应该是最受欢迎的答案。它提供了一个使用场景,说明在没有char类型时不会实例化std::basic_string - hlin117
我如何输出std::basic_string<unsigned int>的cout<<?它一直报错。 - InQusitive

0

只是对大家的回答做了一点小补充。由于 std::stringbasic_string 的一个特化,除了 char 类型之外,它还默认一些其他参数。basic_string 可以有自定义的 char 类型 (例如,basic_string 可以有 wide_chars),自定义的 char_trait (例如,basic_string 可以有 wide chars 但支持普通字符的所有操作),以及自定义的分配器 (basic_string 可以有一些额外信息与其打包,用于自定义调试器或静态内存管理)。

有用性

std::string 将所有这些参数默认为合理的值,因为在大多数情况下,你只需要一个 std::string ,这就是它的有用性。另一方面,当你需要更多自定义的东西时,可以使用 std::basic_string。所以两者都有不同的目的。


0

std::basic_string是一个模板,它允许我们创建typedefs,例如将std::string作为std::basic_string和将std::wstring作为std::basic_string<wchar_t>,因此std::string是std::basic_string的一种特定类型。

如果您正在使用其他类型的IO,std::basic_string可能会在那里很有用。对于任何*curses库,您可能需要为std::basic_string<cchar_t>和libcaca和aalib使用的任何结构体制作typedef以绘制到屏幕上。

std::basic_string对于许多流或类似字符串的解析非常有用。想象一下,您正在为游戏构建一个脚本化的对话系统。您想存储对话框中的字符串,但您还需要编码操作,例如屏幕抖动、更改显示的图像或触发某个屏幕角色上的动画。您可以使用一个struct/union来保存每个字符或操作,并具有该类型的std::basic_string。如果您想以不同的方式处理事物,您可以拥有类似这个结构体的std::basic_string。

struct Color {
  uint8_t r;
  uint8_t g;
  uint8_t b;
};

struct Word {
  std::string value;
  uint32_t fadeInTimeInMs;
  Color textColor;
  uint8_t fontId;
  uint8_t textSize;
};

那么你的源代码可能看起来像这样。

In our {color:{100,100,100}family,} there {textSize:{8},fadeInTimeInMs:{750}was {textSize:{10},textColor:{150,0,30}no} clear} line between religion and fly fishing.

你可以将它解析为std_basic_string,然后在渲染到屏幕时使用每个单词的样式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接