使用size_t作为"for loop"的限制器

Using a size_t as limiter for a "for loop"

本文关键字:for loop 限制器 作为 size 使用      更新时间:2023-10-16

我正在我的s6上使用一个名为CppDroid的C++应用程序来制作一个快速程序。

如何使用size_t作为计数器上"for 循环"的限制器?

int c;
//... more codes here...
    for (c=0; c < a.used; ++c)
        //... more codes here...

a.used是许多使用的数组,来自一个解决方案,用于制作动态大小的数组

错误是:不同符号的整数比较:"int"和"size_t"(又名无符号整数(

for 循环是程序的内部嵌套循环之一,因此我想尽可能将变量 c 维护为"int"。

我看过关于比较 int 和 size_t 的例子,但我不确定它有什么帮助,因为它是针对"如果"条件的。

只需使用 std::size_t c 而不是 int c

只要a.used在迭代过程中没有改变,一个常见的成语是:

for(int c=0, n=a.used; c<n; ++c) {
    ...
}

通过这种方式,强制转换隐式发生,并且您还可以在循环体中方便地n"元素总数"变量。此外,当n来自方法调用(例如,vec.size()(时,您只需计算一次,效率略高。1


1. 理论上,编译器可以自己进行这种优化,但是对于像std::vector这样的"复杂"东西和一个非平凡的循环体,证明它是一个循环不变量是非常困难的,所以它经常只是在每次迭代时重新计算。

关于

"

不同符号的整数比较:"int"和"size_t">(又名无符号整数(

这是一个警告。这不是阻止创建可执行文件的错误,除非您已要求编译器将警告视为错误。

解决该问题的一种非常直接的方法是使用演员表,int(a.size) .

更一般地说,我建议定义一个通用函数来做到这一点,例如命名n_items(C++17 将有一个size函数,不幸的是,它的结果是无符号的,并且将两个或多个逻辑函数混为一谈,因此取名(:

using My_array = ...; // Whatever
using Size = ptrdiff_t;
auto n_items( My_array const& a )
    -> Size
{ return a.used; }

然后对于您的循环:

for( int c = 0; c < n_items( a ); ++c )

顺便说一下,重用变量通常不是一个好主意™,就像这里的c一样。我假设这种重用是无意的。上面的示例显示了如何在for循环头中声明循环变量。


此外,正如Matteo Italia在他的回答中指出的那样,如果测量显示这是一个瓶颈,那么手动优化这样的循环有时是一个好主意。这是因为编译器无法轻松证明 n_items 调用或任何其他动态数组大小表达式的结果在循环体的所有执行中都是相同的("不变"(。

因此,如果测量告诉您可能重复的大小表达式评估是一个瓶颈,您可以例如

for( int c = 0, n = n_items( a ); c < n; ++c )

值得注意的是,任何手动优化都会带来成本,这些成本不容易衡量,但足够严重,通常的建议是推迟优化,直到测量告诉你它确实需要。