2

我的钳位宏有问题,当我的值超过 10 并且我的最高值超过 17 时,它停止工作。任何的想法?

#define CLAMP(value, low, high) (((value)<(low))?(low):(((value)>(high))?(high):(value)))
4

4 回答 4

15

我建议使用比宏更安全的方法:

template <typename T> T CLAMP(const T& value, const T& low, const T& high) 
{
  return value < low ? low : (value > high ? high : value); 
}
于 2010-11-04T19:51:49.587 回答
4

你的宏没问题。如果你传入的 ahigh小于low,你会看到奇怪的结果,但这不太可能是原因。

最可能的结果是您传入的表达式具有副作用,例如使用++运算符或调用函数。如果您有一个具有副作用的表达式,那么由于宏替换的工作方式,副作用可能会发生多次。例如:

CLAMP(x++, low, high)  // expands to:
(x++ < low) ? low : ((x++ > high) ? high : x++);

x++被多次评估,这绝对不是您想要的(由于缺少序列点,这是未定义的行为)。

我建议将宏重写为模板:

template <typename T> T CLAMP(T value, T low, T high)
{
    return (value < low) ? low : ((value > high) ? high : value);
}
于 2010-11-04T19:53:54.467 回答
3

使用已经建议的模板函数是更好的解决方案。

无论如何,如果您遇到此类问题(无论是宏还是函数),您都应该简化表达式;看看这个伪代码:

max(a,b): a>b ? a : b
min(a,b): a<b ? a : b
clamp(x,lo,hi): min( hi, max(lo,x) )
于 2010-11-04T19:57:53.303 回答
-1

你也可以把它变成一个inline函数,这样它就像一个宏但更安全。

于 2010-11-04T19:56:24.600 回答