这个问题与这个问题有关,但不完全相同。
除了与可读性相关的问题之外,使用std :: vector<char>
代替std :: string
来保存任意二进制数据是否有任何好处?
也就是说,与使用字符串相比,是否有任何易于执行/更有效率/更好的任务可以使用向量来完成?
除了易读性(不应低估)之外,我可以想到一些使用 std::string
而非 std::vector
的一些小型性能/内存问题:
一些现代的 std::string
实现采用了小字符串优化。如果你存储的数据大于 string
内部缓冲区的大小,则会导致劣化,降低复制、移动和 swap
的效率1,并增加 sizeof()
的大小而没有任何好处。
一个高效的 std::string
实现将始终分配至少比当前大小多 1 个字节以存储终止 null(如果不这样做,则需要在 operator[]
中额外处理 str[size()]
)。
我应该强调,这两个问题都非常小;它们的性能成本很可能会被淹没在背景噪音中。但是您确实提出了这个问题。
1如果使用小字符串优化,则这些操作需要在 size()
上进行分支,而在良好的 std::vector
实现中则不需要。
vector<char>
确实比string
具有更多的功能。与string
不同,vector<char>
在swap
操作期间保证保留迭代器、引用等。参见:May std::vector
make use of small buffer optimization?
std::string
的目的之外,功能上没有太大的区别。当然,如果效率是唯一的考虑因素,您也可以考虑char*/malloc。std::string
默认存储<char>
。如果您以后需要处理另一种类型(例如unsigned short),您可能需要执行以下操作之一:std::basic_string<unsigned short>
(这将使您远离正常的std::string
处理)
- 在setter中暂时应用一些reinterpret_cast逻辑。std::vector<unsigned short>
即可。std::vector<unsigned short>
相比,使用std::basic_string<unsigned short>
的缺点是什么? - user541686std::char_traits<unsigned short>
不是标准所必需的。 - Bo Perssonchar
和wchar_t
作为有效的char_traits。如果你在内容上运行字符串操作,使用其他东西可能会导致未定义的行为。 - seanhodges向量
:vector<char> a, b;
// ...
vector<char> c;
c.insert(c.end(), a.begin(), a.end());
c.insert(c.end(), b.begin(), b.end());
string
:string a, b;
// ...
string c = a + b;
vector<char>
相对于string
的优势,而不是反过来...看到你只是引用其他答案并在这个方面发表自己的回答,有点奇怪。 - user541686string
而不是vector<char>
的原因,所以这并不是我需要回答的问题。 - user541686我认为你从中唯一获得的好处就是可以轻松地递增字符的std::vector
,但即使如此,也可以使用std::string
来完成。
你必须记住,即使std::string
看起来像一个对象,它也可以像数组一样访问,因此甚至可以在不使用std::vector
的情况下访问字符串的特定部分。
理想情况下,我们应该使用vector<unsigned char>
来存储任意二进制数据 - 但我认为你已经知道这一点了 - 因为你提到了旧问题。
除此之外,使用向量肯定会更节省内存,因为字符串会添加一个终止的Nul字符。性能也可能会提高,因为两者的分配机制不同 - 向量保证连续的内存!
此外,使用字符串是不正确的,因为调用者/用户可能会无意中调用一些字符串方法,这可能会导致灾难。
length()
应该会给出正确的长度。问题出现在用户开始使用 c_str()
,然后想知道为什么他们的字符串被截断了。 - tinman