【问题标题】:Is it good practice to use size_t in C++?在 C++ 中使用 size_t 是一种好习惯吗?
【发布时间】:2009-07-11 16:09:00
【问题描述】:

我见过人们在表示无符号整数时使用size_t。例如:

class Company {
  size_t num_employees_;
  // ...
};

这是好的做法吗?一件事是你必须包括<cstddef>。应该改为unsigned int 吗?甚至只是int

只使用int 听起来对我很有吸引力,因为它避免了像这样的愚蠢错误(因为人们经常使用int):

for(int i = num_employees_ - 1; i >= 0; --i) {
   // do something with employee_[i]
}

【问题讨论】:

  • 我不知道有谁会从大小向下计数到 0。:|
  • 我很好奇关于选角的答案。如果您使用 unsigned int 或 int 并且这不是系统上的 size_t 实际值,那么大概它必须对其进行转换,因此可能会影响性能?
  • 它可能很有用,但按照示例显示的方式进行操作只是不好的做法。选择数据类型以满足不良做法会导致两种不良做法。
  • @GMan:好吧,如果有一个 函数 可以返回项目的数量,那么倒数会很有用:for(int i=getNum()-1; i >=0; --i) 因为如果你只是向上计数,那么该函数将被多次调用(潜在的性能问题)。
  • 在这种经济环境下,您经常将员工数归零。听说过“后进先出”吗?

标签: c++ types


【解决方案1】:

size_t 的大小可能与int 不同。

对于员工人数等因素,这种差异通常是无关紧要的;有多少人拥有超过 2^32 名员工?但是,如果您是一个表示文件大小的字段,如果您的文件系统支持 64 位文件,您将希望使用 size_t 而不是 int

请注意对象大小(由sizeof 获得)属于size_t 类型,而不是intunsigned int;同样,相应地,有一个ptrdiff_t 表示两个指针之间的差异(例如,&a[5] - &a[0] == ptrdiff_t(5))。

【讨论】:

  • 您应该对文件大小使用 off_t,而不是 size_t。在 32 位系统上,size_t 将是 32 位,而 off_t 将是 64 位(假设支持大文件)。
  • @Søren:+1 非常好的观点。我将尝试考虑另一个示例,其中 64 位 size_t 出现,然后更新我的帖子。欢迎您提出任何建议。 :-)
【解决方案2】:

在你的情况下,不要使用它们中的任何一个。要么使用容器和迭代器,要么创建提供迭代器/范围访问的新数据类型(例如员工数据库)。

至于未签名,Bjarne Stroustrup 在 TCPL 中写道:

无符号整数类型非常适合用于处理存储的用途 作为位数组。使用无符号而不是 int 来获得 多一位来表示正整数几乎从来都不是一件好事 主意。尝试通过声明来确保某些值是正数 无符号变量通常会被隐式所击败 转换规则。

【讨论】:

    【解决方案3】:

    在许多情况下使用 size_t 有助于提高可移植性。 size_t 并不总是“无符号整数”,但它始终是可以表示给定平台上最大可能对象的大小。例如,某些平台具有 16 位整数大小,但使用 32 位指针。在这种情况下,如果您使用 unsigned int 来表示某些内容的大小,您会将其限制为 65,536 字节(或其他元素),即使平台可以处理更大的内容。

    在您的示例中,我可能会对 32 位或 64 位无符号整数使用 typedef,而不是使用 int 或 unsigned int 或 size_t。

    【讨论】:

      【解决方案4】:

      你总是可以使用类似的东西

      employeeList.size();
      

      EmployeeList::size_type i = 0;
      

      EmployeeNumber number = employee.getNumber();
      

      我的意思是要封装 int 和其他类似的类型,除非它只是一些内部计算或算法。

      【讨论】:

        【解决方案5】:

        size_t 专门用于指定值的内存大小(以字节为单位)。它是 sizeof 表达式的类型。

        您应该只为此目的使用 size_t,对于其他事情您应该使用 int 或定义自己的类型。

        另见Wikipedia

        【讨论】:

          【解决方案6】:

          在这种情况下,我会使用 unsigned intintsize_t 似乎主要用于表示数据结构的大小。从概念上讲,虽然员工数量在某些情况下可能是数据结构的大小,但不一定;这可能只是一个计数。所以我会使用int,但我可能不会过于强调这一点。

          【讨论】:

            【解决方案7】:

            我不是专业人士,但我只使用size_t 来表示内存大小以增加代码的可读性。在其他所有情况下,我都使用unsigned int(或其他任何东西)。

            【讨论】:

              【解决方案8】:

              我想说,使用size_t 不仅用于内存区域的大小,而且用于索引(如for-loop 中的索引变量)一定不是一种糟糕的 C++ 风格,因为在C++ 参考我们看到definitions 喜欢:

              T& operator[](size_t i) const;
              

              (这个例子来自标准的unique_ptr模板类。)

              因此,标准运算符旨在用于索引数组元素,其参数的类型恰好是size_t

              【讨论】:

                【解决方案9】:

                在这种情况下,您不想使用普通 int,因为员工人数永远不会是负数,并且您希望编译器帮助您执行此规则,对吗?

                【讨论】:

                • 好吧,如果我收到编译器或运行时警告,我会很高兴:num_employees_ = 0; --num_employees_;但它不会发生。
                • @dehmann 但是您可以编写将 unsigned int 作为参数的函数/方法,当用户传递纯 int 时,它们会被警告。
                • @Piotr:不,他们不会。 "void foo(unsigned int a) {} int main() { int a = -1; foo(a); }" 不会对我知道的任何编译器发出警告。传递否定文字确实如此。
                猜你喜欢
                • 2011-02-28
                • 2019-03-11
                • 1970-01-01
                • 1970-01-01
                • 2017-09-18
                • 2013-08-03
                • 1970-01-01
                • 2019-03-06
                • 2013-03-30
                相关资源
                最近更新 更多