【问题标题】:What are differences between std::string and std::vector<char>?std::string 和 std::vector<char> 有什么区别?
【发布时间】:2021-03-23 16:25:19
【问题描述】:

那么主要区别是什么?在哪些情况下会用到它们?

【问题讨论】:

  • 我看不出 std::vector 有什么用处
  • 它们是不同的容器。它们可能有很多相似之处,但仅此而已。尝试调用 std::vector&lt;char&gt; 对象的 c_str() 成员。
  • 在内部它们都是chars 的动态数组,但是它们的界面是完全不同的。看看en.cppreference.com/w/cpp/string/basic_stringen.cppreference.com/w/cpp/container/vector
  • string 在向量末尾保留一个额外的字节,该字节始终设置为 0。当您调用 size() 时,它不包括该字节。但是,它存在于 c_str() 运算符中,因此它不必在每次调用 c_str 时复制数据。

标签: c++


【解决方案1】:
  • vector&lt;char&gt; 为您提供&amp;v[0]+n == &amp;v[n] 的保证,而字符串没有(实际上是这样,但不能保证)...AFAIK C++0x 已经提供了该保证
  • 没有从const char*vector&lt;char&gt; 的隐式转换
  • 字符串不是 STL 容器。例如,它没有 pop_back()back() 函数
  • 最后但同样重要的是,不同的成员函数! String 为您提供适合字符串的函数,例如使用 c_str() 返回一个以 null 结尾的字符串

底线:当您需要对字符串进行操作时,请使用string。当你需要一个......好吧,单个字符的向量时,请使用vector&lt;char&gt;......

vector&lt;char&gt; 的另一种用法是避免vector&lt;bool&gt; 特化。

【讨论】:

  • 好的,谢谢@Armen。那么二进制数据呢,我可以把它保存在字符串中吗?这将适用于所有平台str += "\01512";
  • @Mihran:那个二进制文件怎么样?它会将您提到的字符附加到字符串
  • 但它不能以错误的方式从右操作数“\01512”生成字符串(即空字符串,因为文字以\0开头)然后将这个空字符串连接到我们的str吗?
  • 有一个字符串构造函数,它采用字符串的开始和结束迭代器,即使该字符串中嵌入了空字符,它也会遵守该长度。 std::string 操作也将嵌入的 null 视为字符串的一部分。问题是当您将字符串传递给其他使用它的对象时,就像 C 字符串一样。
  • C++11 添加了pop_back()back() 等。
【解决方案2】:

std:string 用于字符串表示,并具有特定于字符串操作的方法,例如substrcompare

您还有c_str 方法,该方法将返回指向有效“C 字符串”的指针,您可以将其用作仅以const char* 作为参数的函数的参数,因为它可以保证返回的字符串以零结尾。

std::vector&lt;char&gt; 将只是一个字符数组,最大的问题是因为你没有 c_str 方法,所以你不能将它作为参数传递给采用 const char * 的函数,除非你照顾始终在向量末尾保持 0。

【讨论】:

  • 类似substr的函数也存在于向量中,即std::copy
  • 是的,但它们不是成员函数,例如 substr。我也可以将 std::copy 与 std::string 一起使用。
【解决方案3】:

std::vector&lt;char&gt; 可以像 std::string 一样使用,但反过来则不然。

std::vector&lt;char&gt; 只存储字符序列,但并非所有字符序列都是字符串。考虑二进制数据,它将正确存储在std::vector&lt;char&gt;(或std::vector&lt;unsigned char&gt;)中;将其存储在字符串中是没有意义的。

在内部,std::string可以以与 std::vector&lt;char&gt; 大致相同的方式实现——实际上,您可以将其视为在概念上相同——但在实践中,有几个重要的区别:

  1. C++11 introduced the requirement that a std::string is required to store a NUL-terminated sequence of characters internally。这使其合规,并使与 C 样式字符串的互操作更容易。显然,std::vector&lt;char&gt; 不会有与它相关联的要求,您也不会想要它。

  2. std::stringstd::vector&lt;&gt; 相比提供了一个非常不同且扩展了很多的界面。虽然后者只是一个无聊的旧元素序列,但前者实际上是为表示一个字符串而设计的,因此提供了各种与字符串相关的便利功能。 (有些人会争论too many,宁愿这些作为独立的“免费”函数实现,而不是特殊“字符串”类的成员函数。)

  3. std::string 的常见实现将使用称为"small string optimization (SSO)" 的优化,当您存储直接适合std::string 对象实例的字符串时,它可以避免动态内存分配。在std::vector&lt;&gt;(尽管it could actually be implemented in a custom vector type)中找不到这种优化。

    而且,为了启用小字符串优化,标准要求交换 std::string 使其迭代器无效。该要求不适用于std::vector&lt;&gt;

  4. 虽然现在可能只是历史上的好奇心(特别是因为在实践中几乎没有标准库的实现以这种方式工作),但在 C++03 和早期版本的语言标准中,std::string 不是 em> 需要将字符串中的字符存储在连续内存中。换句话说,它实际上不必作为数组的包装器来实现。这允许在底层使用 rope data structure 和/或写时复制策略之类的东西。 std::vector&lt;&gt; 总是需要对其元素进行连续存储。 (C++11 对std::string 引入了同样的要求。)

【讨论】:

    【解决方案4】:

    std::string 针对典型的字符串处理操作进行了优化,参见例如http://www.cplusplus.com/reference/string/string/“字符串操作”的最后一段。

    std::vector 是任何类型数据的通用容器,不仅是字符,因此对于人们通常只对字符串执行的操作没有具体的支持。

    用于处理字符串的函数通常支持string,但不支持vector&lt;char&gt;

    【讨论】:

    • 我不是在问什么是 std::string 和什么是 std::vector.
    • 如果您的数据代表一段文本,请使用string,因为它是为此目的而创建的,并且支持人们通常对文本执行的操作。但你当然知道这一点。你的问题我不清楚。
    【解决方案5】:

    为什么要比较这些不同的数据类型? std::string 是一个库,提供如下简单的字符串处理:

    std::string myString;
    myString = "My Funny Text";
    size_t startOfFunny = myString.find("Funny");
    

    std::vector 没有字符串操作函数,因为它只是一种容器。如果您需要彼此独立地存储chars,您将使用它。

    【讨论】:

      猜你喜欢
      • 2023-04-09
      • 2014-10-24
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      • 2016-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多