模板化的数学函数是否接受值或const引用
Should templated math functions take values or const references?
假设我想实现一些简单的数学函数;例如,假设它是(c++ 17的)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&
的,而不是值。因此,为了使引用更简单,例如:
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
持续时间)? - 为什么在任何相对简单的(constexpr?),无副作用的数学函数的一般情况下,采取
const&
然后一个值是一个更好的主意?
指出:
- 我意识到当你有某种k维向量类型或
boost::rational
s和其他类似数字的类型时,采取const&
可能开始有意义;但即使这样,编译器不会优化复制吗? - 我不是询问任何任意的c++函数以及它是否应该按值取参数,这显然是一个坏主意。
号
- 是否有任何好处采取const引用,
T
的是简单的数字类型?
号
- 同上,对于类型是一些抽象的东西包装单个数字作为数据成员(例如
std::chrono
持续时间)?
- 为什么在任何相对简单的(constexpr?),无副作用的数学函数的一般情况下,采取
const&
比值更好?
想象一个使用动态分配的bigint类型;复制这样的类型是很昂贵的。
编译器不会优化复制吗?
只有当它能证明复制值没有副作用时才行,除非所有涉及的代码对编译器可见,否则很难做到这一点。(因此,如果您的bigint使用GMP,那么您就不走运了。)
对于简单的数字类型
T
来说,使用const引用有什么好处吗?
不,我不这么认为,但也没有惩罚。
同上,对于一些抽象的东西包装单个数字作为数据成员的类型(例如
std::chrono duration
)?
同上。
为什么(它是在所有)一个更好的主意采取
const&
然后在一般情况下的值?
标准库算法不仅为基本类型设计,也为用户定义的类型设计,复制这些类型的成本可能并不低。对于这些类型,使用const&
避免了复制的惩罚,同时不影响基本类型的使用。
相关文章:
- 在 const 函数中通过引用和指针返回之间的区别
- 使用对const结构的const数组的引用进行构造
- 将const引用参数初始化为默认参数会导致悬空引用吗
- 在C++17中,引用const字符串的语义应该是什么
- 为什么当我为 for(auto& it : myUnorderedMap) {... = std::move(it.second)} 时,我会得到一个 const 引用?
- 类型为 "Bucket&"(未限定的 const 限定)的引用不能使用 "SortedList." 类型的值进行初始化 如何修复此错误?
- 为什么在引用指针时将 const 放在 & 符号的左侧有效,而在右侧则无效?
- 将返回类型专用化为 void 或 const 左值引用
- 在其他容器中使用 boost::container::static_vector 时,GCC 编译错误"将'const s'绑定到类型's&'的引用丢弃限定符"
- 在 C++ 中通过引用传递类成员时,Const 不起作用
- 我们可以有一个 setter 成员函数作为从 const 对象引用的 const 吗?
- 将对象传递给函数而不将其包装到 std::ref 中,而参数被指定为 const 引用
- 错误:对类型 'const ItemInstance' 的引用无法绑定到类型 'void' 的右值
- 包括"lvtocon.h",未定义对'operator<<(std::ostream&, char const*)的引用
- 如何在构造函数中传递 const 引用时强制编译器不接受右值
- 通过使用 const-cast 的非常量引用来延长临时的寿命
- const TYPE&- 我什么时候想通过引用 const 来使用?
- 指针引用const null值
- 三元运算符和通过引用const延长临时对象的生存期
- 为什么必须引用const来避免复制形参?