C++ 我的clamp宏有问题

C++ 我的clamp宏有问题,c++,macros,clamp,C++,Macros,Clamp,我的clamp宏有一个问题,当我的值超过10并且我的上限超过17时,它停止工作。有什么想法吗 #define CLAMP(value, low, high) (((value)<(low))?(low):(((value)>(high))?(high):(value))) 定义钳位(值、低、高)(((值)(高))?(高):(值))) 我建议使用比宏更安全的方法: template <typename T> T CLAMP(const T& value, cons

我的clamp宏有一个问题,当我的值超过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); 
}
模板T夹(常数T和值、常数T和低、常数T和高)
{
返回值<低?低:(值>高?高:值);
}

您的宏很好。如果您传入的
高值
小于
低值
,您将看到奇怪的结果,但这不太可能是原因

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

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

您还可以将其设置为
内联
函数,使其类似于宏,但更安全。

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

无论如何,如果你有这样的问题(无论是宏还是函数),你应该简化你的表达式;看看这个伪代码:

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

min(a,b):调试宏时要做的第一件事是展开宏,看看为什么会得到不正确的结果。+1,但我建议
template
@Beta:这样它会捕获潜在的危险类型转换。但是你的方法也会起作用,没有理由像那样将if-else语句打包到模板函数中+1否则(就个人而言,我不会因为函数替换了函数中的宏而将函数命名为全大写)。这是迄今为止最好的答案。Nit:所有大写名称都应保留给宏。干杯,@Beta:standard
std::max()
使用单一类型,而不是您建议的三种类型。在某个时间点,Alexandrescu在“仅”174行代码中编写了C宏的完全正确的类型安全版本。标准委员会决定,
std::min
模板存在的问题(要求两个参数属于同一类型,如果参数属于不同类型,则失败)不值得Alexandrescu提案所要求的更改。有时简单的方法已经足够好了。为什么还要保留三元运算符呢?为什么不用两个
if
语句和三个
return
重写它呢?这是答案,与问题无关。
max(a,b): a>b ? a : b
min(a,b): a<b ? a : b
clamp(x,lo,hi): min( hi, max(lo,x) )