質問

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

#define CLAMP(value, low, high) (((value)<(low))?(low):(((value)>(high))?(high):(value)))
役に立ちましたか?

解決

マクロよりも安全な方法を使用することをお勧めします。

template <typename T> T CLAMP(const T& value, const T& low, const T& high) 
{
  return value < low ? low : (value > high ? high : value); 
}

他のヒント

あなたのマクロは大丈夫です。あなたがaで通過した場合 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);
}

すでに提案されているようにテンプレート関数を使用することは、より良いソリューションです。

とにかく、この種の問題(マクロまたは関数の両方)がある場合は、表現を簡素化する必要があります。この擬似コードを見てください:

max(a,b): a>b ? a : b
min(a,b): a<b ? a : b
clamp(x,lo,hi): min( hi, max(lo,x) )

あなたはそれを作ることもできます inline 機能して、マクロのようなものですが、より安全になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top