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:
- Is there any benefit to taking a const reference, for
T
's which are simple numeric types? - Ditto, for types which are some abstract thing wrapping a single number as a data member (e.g. a
std::chrono
duration)? - Why is it (and is it at all) a better idea to take a
const&
then a value in the general case of any relatively-simple, (constexpr?), side-effect-free math-ish function?
Notes:
- I realize taking a
const&
might start making sense when you have, say, some kind of k-dimensional vector type, orboost::rational
s and other numeric-like types; but even then, wouldn't a compiler optimize the copying away? - I'm not asking about any arbitrary C++ function and whether it should just take its parameters by value, that would be a bad idea obviously.