循环遍历所有值

时间:2012-01-31 23:10:40

标签: c++

这可能是一个奇怪的问题,但是如何很好地循环一个类型的所有值。特别是标准的整数类型,例如unsigned short。普通的for循环结构存在一个难点:用于退出循环的条件 - 因为所有值都是有效的。

当然,有几种方法可以完成工作。退出最后一个值,然后在循环后处理。使用更大的int来计算。问题是,有更优雅的方式吗?

7 个答案:

答案 0 :(得分:4)

#include <limits>
int i = std::numeric_limits<int>::min();
do {
    ...
    if(i == std::numeric_limits<int>::max())
        break;
    i++;
} while(true);

这与转换为:

的for()语句形成对比
#include <limits>
int i = std::numeric_limits<int>::min();
while(true) {
    if(i == std::numeric_limits<int>::max())
        break;
    ...
    i++;
};

答案 1 :(得分:4)

我曾经一度担心这个问题,这是我能想到的最好的问题:

unsigned char c = 0;
do
{
    printf("%d ", (int)c); //or whatever
} while (++c != 0);

我发现do..while语法有用的极少数情况之一。

请注意,从技术上讲,它仅对无符号类型有效,因为我依赖于值的包装。

答案 2 :(得分:3)

如果你想要一个漂亮的解决方案,你可以这样做:

for(auto x : everyvalue<short>()) {
  std::cout << x << '\n';
}

everyvalue的位置:

#include <limits>
template<typename T>
struct everyvalue {
  struct iter {
    T x;
    bool flag;
    inline iter operator++() {
      if(x == std::numeric_limits<T>::max())
        flag = true;
      else
        ++x;
      return *this;
    }
    inline T operator*() { return x;}
    inline bool operator!=(iter& i) {return flag != i.flag;}
    // note: missing some iterator requirements, still should work
  };
  inline iter begin() { return iter{std::numeric_limits<T>::min(),0}; }
  inline iter end() { return iter{std::numeric_limits<T>::max(),1}; }
};

否则,首选简单的break

答案 3 :(得分:1)

您可以将增加的值与一个标志组合起来,表示您已达到最大值,因此您不会超过它:

for ( char i ( std::numeric_limits<char>::min() ), j ( 1 );
      i != std::numeric_limits<char>::max() || j--;
      i += j )
    std::cout << ( int ) i << '\n';

但只有'复杂'而不是'干净的简单线'才优雅。

答案 4 :(得分:0)

答案 5 :(得分:0)

您可以使用更大的类型:

unsigned long i;
for (i = std::numeric_limits<unsigned short>::min();
     i <= std::numeric_limits<unsigned short>::max();
     i++)

答案 6 :(得分:0)

我最近问了一个关于bools的问题:How to write a `for` loop over bool values (false and true)。你可以在那里寻找答案。然后我意识到,由于for循环迭代所有可能的值将需要再次评估条件,您需要一个额外的值(以任何形式 - 更大的类型,第二个变量等)来正确区分所有情况。并且,do-while循环适用于这种情况,因为它需要与不同值一样多的比较。