#定义或键入函数

#define or typed function?

本文关键字:函数 定义      更新时间:2023-10-16

不确定这两种方式哪个更好(更快(:

// first
#define BOUNDED(x,lo,hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x))
// second
double Bounded(double x, double lo, double hi) {
    return fmax(fmin(x, hi), lo);
};    

在两者中,我都将它们与double一起使用。它取决于编译器吗?

C++的经验法则是尽可能避免使用宏。

例如,如果我传递类似BOUNDED(x++, low++, hi++)的内容,您的宏将遭受参数的重复评估。

如果你想保留宏的通用性,那么为什么不写呢

template<typename Y>
inline Y Bounded(Y x, Y lo, Y hi)
{
    return x < lo ? lo : x > hi ? hi : x;
}

我看不出这比宏观方法更慢。请注意,编译器可能会忽略inline,因为它认为合适。确定性能档案。对于大型类型,您可以考虑传递const Y& x等,但对于Y=double的情况,这可能会减慢。

如果我是你,我会选择函数并将其模板化为constexpr:

template<typename T>
constexpr T Bounded(T x, T lo, T hi)
{
    return x < lo ? lo : x > hi ? hi : x;
}

这样你就有了通用的方法(和宏一样(,但有两个优点:

  1. 您可以使用概念(一旦它们进入标准:(来约束传递到模板中的类型
  2. 如果传递constexpr参数,将在编译时对其进行求值

至于你的确切问题:

现代编译器擅长优化。其实很好。我怀疑,由于这些优化,两个版本的执行时间相似。但是,如果不对您的构建配置进行分析,那只是胡乱猜测。

为了完整起见,我将添加它。一旦出现c++17,您就可以使用std::clamp

template<class T>
constexpr const T& clamp( const T& v, const T& lo, const T& hi );
template<class T, class Compare>
constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp );
  1. 如果v比较小于hi则返回v和lo中的较大者,否则返回v和hi中较小的一个。使用运算符<比较值
  2. 与(1(相同,但使用comp来比较值

我想,你应该信任c++编译器,使用函数而不是宏,因为它可以执行一些优化,比如内联(这将为你做所有必要的工作(。此外,在c++中使用宏是不好的做法,这可能导致错误