【问题标题】:std::size_t or std::vector<Foo>::size_type?std::size_t 还是 std::vector<Foo>::size_type?
【发布时间】:2017-12-23 10:20:51
【问题描述】:

当我在std::vector&lt;Foo&gt;(或每个具有随机访问迭代器的容器)上循环时,我使用一个无符号整数变量i。如果我想尊重规范,我应该使用std::size_t还是容器本身给出的类型:std::vector&lt;Foo&gt;::size_type

如果我选择std::size_t(出于可读性原因),我能否确定std 命名空间中每个容器的每个实现都使用std::size_t 作为size_type

注意:我只使用 C++98(出于兼容性原因)。

【问题讨论】:

  • 不,你不能确定。如果您想避免可能的缩小转换,请使用容器提供的类型。
  • 在 64 位 Linux 机器上,size_t 可以是 unsigned long 的 typedef 和 std::vector::size_type 可以是 unsigned long long。两者都是 64 位宽,范围相同,但类型不同。 (example)
  • 您可以使用模板类,根据std::size_tstd::vector&lt;T&gt;::size_type 是否具有相同的大小来选择要使用的类型(我现在无法尝试实现它,但我'我很确定这是可行的)。
  • @NathanOliver :最初,我有这种反应是因为我在任何地方都错误地使用了unsigned long int(可以使用gcc,std::size_tunsigned long int)。现在我在使用std::size_tunsigned long long int 的英特尔编译器移植到Windows 时遇到了兼容性问题。 :-/

标签: c++ stl c++98 size-t size-type


【解决方案1】:

std::vector&lt;Foo&gt;::size_typestd::size_t 相同并不一定正确。即使对于 C++11 也是如此。

但我个人将std::size_t 用于std::vector 索引,而与类型无关。

如果你感觉特别勤奋,你总是可以使用静态断言。显然,static_assert 是 C++98 中后来添加的内容,但在该标准中,您可以使用类似

static char wrong_size_1[1 + sizeof(std::size_t) - sizeof(std::vector<Foo>::size_type)];

static char wrong_size_2[1 - sizeof(std::size_t) + sizeof(std::vector<Foo>::size_type)];

如果类型类型大小不同,则会导致编译时失败。

【讨论】:

  • 实际上,我已经在 boost 中使用了静态断言。好主意!
  • 哇。 Boost 仍然支持 C++98!你知道,它们是好鸡蛋。
  • 我将 boost 1.57 与 GCC 4.4.7 一起使用,没有任何(已知)问题。 ;-)
【解决方案2】:

我可以确定 std 命名空间中每个容器的每个实现都使用 std::size_t 作为 size_type 吗?

不,你不能。但是在实践中,您可以相信std::size_t 对于基于单个数组的向量或任何其他容器来说足够大,因为

size_t 可以存储理论上可能的任意类型(包括数组)对象的最大大小。

【讨论】:

  • 对象的最大尺寸很可能远大于向量的最大size_type。当 T 是向量中的内容时,std::vector&lt;&gt;::type 的范围仅为 0 到 numeric_limits&lt;size_t&gt;::max() / sizeof(T)。我要说的是,这种担心可能会缩小转换范围。
  • @StoryTeller 如果您的整数太小而无法索引向量的对象,我会担心。 std::size_t 至少和它需要的一样大,所以它可以代表任何索引。在最坏的情况下,它会浪费一点点内存。
  • 如果它太小,您将有无法访问的元素。如果它太大,你会“环绕”并可能在错误的地方修改元素。我认为一个比另一个更容易捕获。缩小转换范围有点邪恶。
  • @StoryTeller 你从哪里得到这个“环绕”的值?因为它比size_type 的大小要大,所以它不可能是一个有效的索引,所以你不可能得到这个元素。使用size_type 不会更容易解决错误,它只是将环绕点移动到另一段代码。
  • “它不可能是一个有效的索引”。除了 C++ 将愉快地执行隐式缩小转换。对于无符号整数,它被很好地定义为模 2 到某个幂。因此包装。
猜你喜欢
  • 2018-02-15
  • 2012-03-07
  • 2012-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-11
  • 2020-03-06
  • 2016-12-05
相关资源
最近更新 更多