带有size_t循环变量的后向循环

时间:2014-04-23 06:46:30

标签: c++

以下代码是否定义了行为,我的意思是i--当i为0时,将始终是size_t可表示的最大无符号int,对吧?那么在我的代码中使用它是否完全安全?

size_t NPOS = -1;
for(size_t i = vec.size()-1; i!= NPOS; i--)

4 个答案:

答案 0 :(得分:3)

这是使用神话般的操作员的经典场景:

for (size_t i = vec.size(); i --> 0; )

答案 1 :(得分:1)

在班级std::basic_string中,静态数据成员npos的定义方式如下

static const size_type npos = -1;

考虑到成员函数size()的返回值类型为size_type。所以你的代码是有效的

size_t NPOS = -1;
for(size_t i = vec.size()-1; i!= NPOS; i--)

如果表达式vec.size()-1的值可以存储在类型size_t

所以更有效的代码看起来像

for ( std::vector<T>::size_type i = vec.size()-1; i != std::vector<T>::npos; i-- )

虽然我会按以下方式编写循环

for ( std::vector<T>::size_type i = vec.size(); i != 0;  )
{
   //...
   // using expression vec[--i]
   // or
   //  --i
   // vec[i]
   //...
} 

答案 2 :(得分:1)

从技术上讲,它是有效的,因为-1转换为。{ 无符号类型保证最大可能 值,从0递减。不过,这不是什么 我会考虑好的做法。如果你只是想迭代 反过来一个向量:

for ( auto current = vec.rbegin(); current != vec.rend(); ++ current ) {
    //      Do something with *current
}

如果由于某种原因你确实需要索引:

int i = vec.size();
while ( i != 0 ) {
    -- i;
    //      Do something with vec[i]
}

这个循环更清晰,并且避免了无符号的任何问题 类型换行(虽然如果你需要索引,那可能 意味着你需要它作为算术值,所以你应该避免 开头的无符号类型)。

答案 3 :(得分:0)

对于给定的整数类型T,签名或无符号,所有这些都是相同的值:

T a = -1;
T b = 0 - 1;
T c = 0; c = c - 1;
T d = 0; d --;
T e = 0; -- e;

assert(a == b);
assert(a == c);
assert(a == d);
assert(a == e);

这涵盖了您在代码段中的所有用法。整数的内部表示并不重要。有符号-1转换为类似无符号整数的最大值这一事实很有意思,但并不直接重要。以上情况属实,否则算术停止工作。