The Proposal to Introduce a 3-Argument Overload to std::hypot gave the following justification:
We considered proposing a variadic overload of std::hypot, so that it could be further
generalized to compute the Euclidean norm of a vector of arbitrary dimension. However, the
general utility of such a feature is not immediately clear; we judge it best (at least for now) to
relegate such a feature to domain-specific libraries, like the GNU Scientific Library [GSL].
They further justified the need for a three-argument hypothenuse:
The std::hypot function, adopted for C++11 via [N1836] and later [N2009], has proven to be a
useful general math utility function. One major application of this function is the calculation of
the distance between 2 points in a 2-dimensional space. However, this is not useful enough, as
many scientific and engineering applications (e.g. n-body simulations) model points in 3-
dimensional space. [...] Using only the current definition of std::hypot, the distance between 2 points in a 3-
dimensional space can at best be calculated as such:
auto d = std::hypot(x2-x1, std::hypot(y2-y1, z2-z1));
This code is far from optimal because it involves 2 function calls to std::hypot as well as an
extra square-root and power operation.
The obvious implementation of the variadic hypothenuse iterates the two-argument hypothenuse, collapsing two numbers into one with each iteration. My implementation is included below. For three arguments, it is equivalent to the solution the authors described as "far from optimal" in their proposal.
namespace std
{
template<typename Arg1, typename Arg2, typename... Args>
auto hypot(Arg1 arg1, Arg2 arg2, Args... args)
{
return hypot(hypot(arg1, arg2), args...);
}
}
Your implementation with std::pow and std::sqrt is inaccurate and prone to overflow.
In summary:
- There is a strong need for a good two-argument and three-argument hypothenuse.
- The obvious variadic implemenations are either slow or inaccurate, so special cases for two and three arguments are needed anyway.
- There is little need for a hypothenuse with four or more arguments.
- There is need for a vector norm (begin + end iterators, C++20 ranges) but that's a different beast.
hypotis no good, since the whole point of the function is to give precise results in cases where the trivial implementation would suffer overflow or loss of precision in intermediate steps. Writing a good version ofhypoteven for two inputs is not straightforward, let alone n inputs. $\endgroup$