在封闭范围内循环
您将如何修复此代码?
template <typename T> void closed_range(T begin, T end)
{
for (T i = begin; i <= end; ++i) {
// do something
}
}
T 被限制为整数类型,可以是此类类型中较宽的类型,并且可以是有符号或无符号的
begin
可以是numeric_limits
::min() end
可以是numeric_limits
(在这种情况下::max() ++i< /code> 在上面的代码中会溢出)
我有几种方法,但没有一种是我真正喜欢的。
How would you fix this code?
template <typename T> void closed_range(T begin, T end)
{
for (T i = begin; i <= end; ++i) {
// do something
}
}
T is constrained to be an integer type, can be the wider of such types and can be signed or unsigned
begin
can benumeric_limits<T>::min()
end
can benumeric_limits<T>::max()
(in which case++i
will overflow in the above code)
I've several ways, but none I really like.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
也许,
Curses,我的第一次尝试是错误的,上面的修复并不像我希望的那么好。怎么样:
即使 T 不是整数类型,
std::advance
也没有歧义,因为std::advance
采用 2 个参数。因此,如果出于某种原因您想要一个封闭的范围,那么该模板还可以与随机访问迭代器一起使用。或者了解一点集合论怎么样?显然,如果您只在封闭范围内编写一个循环,那么这是一种巨大的杀伤力,但如果您想做很多事情,那么它会使循环代码变得正确。不确定效率:在一个非常紧密的循环中,您可能需要确保对
endof
的调用被提升:输出:
在(2) < endof(2) 为 true,但 omega(INT_MAX)
omega
上使用其他运算符时要小心一点对象。我只实现了演示的绝对最小值,并且omega
隐式转换为T
,因此您会发现您可以编写可能会丢弃的表达式欧米伽物体的“无限”。您可以通过声明(不一定定义)一整套算术运算符来解决这个问题;或者如果 isInfinite 为 true,则在转换中抛出异常;或者只是不用担心它,因为您不会意外地将结果转换回 omega,因为构造函数是显式的。但例如,omegaendof(INT_MAX) 为假。
Maybe,
Curses, my first attempt was wrong, and the fix above isn't as pretty as I'd hoped. How about:
There's no ambiguity with
std::advance
even if T isn't an integer type, sincestd::advance
takes 2 parameters. So the template would also work with for instance a random-access iterator, if for some reason you wanted a closed range of those.Or how about a bit of set theory? Obviously this is massive overkill if you're only writing one loop over a closed range, but if it's something that you want to do a lot, then it makes the loop code about right. Not sure about efficiency: in a really tight loop you might want make sure the call to
endof
is hoisted:Output:
Be a bit careful using other operators on
omega<T>
objects. I've only implemented the absolute minimum for the demonstration, andomega<T>
implicitly converts toT
, so you'll find that you can write expressions which potentially throw away the "infiniteness" of omega objects. You could fix that by declaring (not necessarily defining) a full set of arithmetic operators; or by throwing an exception in the conversion if isInfinite is true; or just don't worry about it on grounds that you can't accidentally convert the result back to an omega, because the constructor is explicit. But for example,omega<int>(2) < endof(2)
is true, butomega<int>(INT_MAX) < endof(INT_MAX)
is false.我的看法:
My take:
这是有效的并且相当清楚:
如果您想捕获
begin >= end
的特殊情况,您需要添加另一个if
就像 Steve Jessop 的解决方案中一样。This works and is fairly clear:
If you want to catch the special case of
begin >= end
you need to add anotherif
like in Steve Jessop's solution.编辑:重新设计以更接近OP。
输出是:
EDIT: Reworked things to more closely match the OP.
The output is: