循环遍历所有值
这可能是一个奇怪的问题,但是如何很好地循环一个类型的所有值。特别是标准积分类型,如unsigned short
。正常的for
循环结构呈现一个难点:用什么条件来退出循环 - 因为所有的值都是有效的。循环遍历所有值
当然,有几种方法可以完成工作。退出最后一个值,然后在循环后处理。使用更大的int来计数。问题是,有没有更优雅的方式?
如果你想要一个漂亮的解决方案,你可以这样做:
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
将是首选。
我要给这个答案一个大绿色的勾号。最终结果是优雅和广泛的。所有丑陋的东西都是一次完成,完成并隐藏起来,这是如何使用C++的重要组成部分(在我看来)。其他一些答案可能会有性能优势,但这并不是我之前的做法。 – wxffles 2012-02-01 20:46:33
你可以只用一个更大的类型:
unsigned long i;
for (i = std::numeric_limits<unsigned short>::min();
i <= std::numeric_limits<unsigned short>::max();
i++)
'我 quasiverse 2012-01-31 23:16:17
是 - 复制/粘贴错误!固定。 – 2012-01-31 23:17:02
+1当然,假设'unsigned long'确实比'unsigned short'大。这是我知道的实现,但我只是指出它不能保证。 – 2012-01-31 23:17:44
#include <limits>
int i = std::numeric_limits<int>::min();
do {
...
if(i == std::numeric_limits<int>::max())
break;
i++;
} while(true);
这是相反的,转化为为()语句:
#include <limits>
int i = std::numeric_limits<int>::min();
while(true) {
if(i == std::numeric_limits<int>::max())
break;
...
i++;
};
我不downvoting,但有符号整数溢出是未定义的行为。 (有关有符号整数溢出出错的示例,请参阅http://*.com/q/7682477) – 2012-01-31 23:19:37
编辑出来并不是什么大问题 – 2012-01-31 23:20:56
我担心关于这个同样的问题一次,这是我能想到的最好的:
unsigned char c = 0;
do
{
printf("%d ", (int)c); //or whatever
} while (++c != 0);
我发现do..while
语法很有用的极少数情况之一。
请注意,从技术上讲,它只对无符号类型有效,因为我依赖于值的包装。
我最近问了一个关于bools的问题:How to write a `for` loop over bool values (false and true)。你可以在那里寻找答案。然后我意识到,因为for循环遍历所有可能的值需要再次评估条件,所以需要额外的值(以任何形式 - 更大类型,第二个变量等)来正确区分所有情况。而且,do-while循环适用于这种情况,因为它需要完全一样多的比较,因为有不同的值。
你可以通过你用标志递增值结合起来,说你已经达到最大,所以你不增加过去吧:
for (char i (std::numeric_limits<char>::min()), j (1);
i != std::numeric_limits<char>::max() || j--;
i += j)
std::cout << (int) i << '\n';
但只有优雅如“复杂”,而不是'干净简单的线条'。
听起来像你试图蛮力的东西?不要尝试使用64位整数,尽管... – Mysticial 2012-01-31 23:12:44