29

哪个是用于保存和访问二进制数据的更好的 C++ 容器?

std::vector<unsigned char>

或者

std::string

一个比另一个更有效吗?
一种更“正确”的用法吗?

4

9 回答 9

30

你应该更std::vector喜欢std::string. 在常见情况下,这两种解决方案几乎是等效的,但std::strings 是专门为字符串和字符串操作而设计的,这不是您的预期用途。

于 2009-10-12T20:23:33.440 回答
15

两者都是正确且同样有效的。使用其中一个而不是普通数组只是为了简化内存管理并将它们作为参数传递。

我使用向量是因为意图比使用字符串更清楚。

编辑: C++03 标准不保证std::basic_string内存连续性。然而,从实际的角度来看,没有商业的非连续实现。C++0x 旨在标准化这一事实

于 2009-10-12T18:49:37.593 回答
4

一个比另一个更有效吗?

这是一个错误的问题。

一种更“正确”的用法吗?

这是正确的问题。
这取决于。数据是如何使用的?如果您要在像 fashon 这样的字符串中使用数据,那么您应该选择 std::string ,因为使用 std::vector 可能会使后续维护者感到困惑。另一方面,如果大多数数据操作看起来像普通的数学或向量,那么 std::vector 更合适。

于 2009-10-12T18:57:44.770 回答
2

在最长的时间里,我同意这里的大多数答案。std::string但是,就在今天,我突然想到为什么实际使用over可能更明智std::vector<unsigned char>

大多数人都同意,使用其中任何一个都可以。但很多时候,文件数据实际上可以是文本格式(现在更常见,因为 XML 已成为主流)。这使得在调试器变得相关时可以很容易地在调试器中查看(这些调试器通常会让您浏览字符串的字节)。但更重要的是,可以在字符串上使用的许多现有函数可以很容易地用于文件/二进制数据。我发现自己编写了多个函数来处理字符串和字节数组,并意识到这一切是多么毫无意义。

于 2017-11-28T17:00:27.823 回答
1

这是对dribeas回答的评论。我将其编写为能够格式化代码的答案。

这是 char_traits 比较函数,其行为非常健康:

static bool
lt(const char_type& __c1, const char_type& __c2)
{ return __c1 < __c2; }

template<typename _CharT>
int
char_traits<_CharT>::
compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
{
  for (std::size_t __i = 0; __i < __n; ++__i)
if (lt(__s1[__i], __s2[__i]))
  return -1;
else if (lt(__s2[__i], __s1[__i]))
  return 1;
  return 0;
}
于 2009-10-13T08:01:30.330 回答
0

就可读性而言,我更喜欢std::vector。在这种情况下,std::vector 应该是默认容器:意图更清晰,正如其他答案已经说过的那样,在大多数实现中,它也更有效。

有一次我确实更喜欢 std::string 而不是 std::vector 。让我们看看它们在 C++11 中的移动构造函数的签名:

向量(向量&& x);

字符串 (string&& str) noexcept ;

那时我真的需要一个 noexcept 移动构造函数。std::string 提供它,而 std::vector 没有。

于 2014-06-24T08:19:08.190 回答
-1

如果您只想存储二进制数据,可以使用bitsetwhich 优化空间分配。否则选择vector,因为它更适合您的使用。

于 2009-10-12T18:47:17.410 回答
-1

比较这 2 并选择更适合您的自己。两者都非常强大,使用 STL 算法......选择对您的任务更有效的自己

于 2009-10-12T19:30:27.573 回答
-1

就我个人而言,我更喜欢 std::string 因为 string::data() 当我希望我的二进制缓冲区以 C 兼容的形式返回时对我来说更直观。我知道向量元素可以保证连续存储在代码中执行此操作感觉有点令人不安。

这是个人开发人员或团队应该为自己做出的风格决定。

于 2009-10-12T21:47:31.283 回答