2

クランプマクロに問題があります。値が10を超え、高さが17を超えると、機能しなくなります。何か案が?

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

4 に答える 4

15

I would suggest using a safer way than a macro:

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

マクロは問題ありません。high未満のを渡すと、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 に答える