这可能是一个奇怪的问题,但是如何很好地循环一个类型的所有值。特别是标准的整数类型,例如unsigned short
。普通的for
循环结构存在一个难点:用于退出循环的条件 - 因为所有值都是有效的。
当然,有几种方法可以完成工作。退出最后一个值,然后在循环后处理。使用更大的int来计算。问题是,有更优雅的方式吗?
答案 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循环适用于这种情况,因为它需要与不同值一样多的比较。