Проблема с моим макросом зажима
У меня проблема с моим макросом зажима, когда, когда мое значение превышает 10, а мой максимум превышает 17, оно перестает работать. Любая идея?
#define CLAMP(value, low, high) (((value)<(low))?(low):(((value)>(high))?(high):(value)))
4 ответа
Я бы предложил использовать более безопасный способ, чем макрос:
template <typename T> T CLAMP(const T& value, const T& low, const T& high)
{
return value < low ? low : (value > high ? high : value);
}
Ваш макрос в порядке. Если вы проходите в 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
функция, так что это будет как макрос, но безопаснее.