Suppose I want to implement some simple mathematical function; for example suppose it's a reimplementation of (C++17's) std::clamp
: This function takes a number, a lower bound and an upper bound, and sets the number to one of those bounds if its out of the range they define. If it's a concrete numeric type, say int
, I would write:
constexpr int clamp(int x, int lower_bound, int upper_bound)
{
return x < lower_bound ? lower_bound : ( upper_bound < x ? upper_bound : x );
}
but if it's a template, I see that the sample implementation which is probably what the standard is going to have uses const&
's rather than values. So, making things simpler for quoting, something like:
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 );
}
My questions are:
T
's which are simple numeric types?std::chrono
duration)?const&
then a value in the general case of any relatively-simple, (constexpr?), side-effect-free math-ish function?Notes:
const&
might start making sense when you have, say, some kind of k-dimensional vector type, or boost::rational
s and other numeric-like types; but even then, wouldn't a compiler optimize the copying away?
- Is there any benefit to taking a const reference, for
T
's which are simple numeric types?
No.
- Ditto, for types which are some abstract thing wrapping a single number as a data member (e.g. a
std::chrono
duration)?
No.
- Why is it (and is it at all) a better idea to take a
const&
than a value in the general case of any relatively-simple, (constexpr?), side-effect-free math-ish function?
Imagine a bigint type that uses dynamic allocation; copying such a type is expensive.
- Wouldn't a compiler optimize the copying away?
Only if it can prove that copying the value have no side effect, which is hard to do unless all the code involved is visible to the compiler. (So, if your bigint uses, say, GMP, you are out of luck.)