1

假设我想实现一些简单的数学函数;例如,假设它是 (C++17's) 的重新实现std::clamp:此函数接受一个数字、一个下限和一个上限,如果它超出了它们定义的范围,则将该数字设置为这些边界之一。如果它是一个具体的数字类型,比如说int,我会写:

constexpr int clamp(int x, int lower_bound, int upper_bound)
{
    return x < lower_bound ? lower_bound : ( upper_bound < x ? upper_bound : x );
}

但如果它是一个模板,我看到可能是标准将使用的示例实现const&使用's 而不是值。因此,使引用变得更简单,例如:

template <typename T>
constexpr T clip(const T& x, const T& lower_bound, const T& upper_bound)
{
    return x < lower_bound ? lower_bound : ( upper_bound < x ? upper_bound : x );
}

我的问题是:

  • 使用 const 引用有什么好处,因为T's 是简单的数字类型?
  • 同上,对于将单个数字包装为数据成员(例如std::chrono持续时间)的一些抽象事物的类型?
  • 为什么在const&任何相对简单的(constexpr?)无副作用的数学函数的一般情况下取一个值是一个更好的主意?

笔记:

  • 我意识到,const&当您拥有某种 k 维向量类型或boost::rationals 和其他类似数字的类型时,可能会开始有意义;但即便如此,编译器不会优化复制吗?
  • 不是在问任何任意的 C++ 函数,以及它是否应该只按值获取参数,这显然是个坏主意。
4

2 回答 2

3
  • 使用 const 引用有什么好处,因为T's 是简单的数字类型?

不。

  • 同上,对于将单个数字包装为数据成员(例如std::chrono持续时间)的一些抽象事物的类型?

不。

  • const&为什么在任何相对简单的(constexpr?),无副作用的数学函数的一般情况下,取 a 比取值更好(而且完全是)一个更好的主意?

想象一个使用动态分配的 bigint 类型;复制这种类型很昂贵。

  • 编译器不会优化复制吗?

只有当它可以证明复制该值没有副作用时,除非所有涉及的代码对编译器都是可见的,否则很难做到这一点。(因此,如果您的 bigint 使用 GMP,那么您就不走运了。)

于 2016-10-12T21:38:13.143 回答
2

使用 const 引用有什么好处,因为T's 是简单的数字类型?

不,我不这么认为,但也没有处罚。

同上,对于将单个数字包装为数据成员(例如 a std::chrono duration)的一些抽象事物的类型?

同上。

const&为什么在一般情况下采用 then 值是一个更好的主意?

标准库算法不仅适用于基本类型,还适用于用户定义的类型,复制起来可能并不便宜。对于这些类型,使用 aconst&可以避免复制的惩罚,同时不会损害基本类型的使用。

于 2016-10-12T21:30:58.787 回答