I have a function which calculates the first derivative dy/dx for discrete values y(x) stroed as std::vector:
vector<double> CalcDerivative(vector<double>&y, vector<double>&x) {...}
Often the spacing dx is constant so it would be more efficient to pass a double to this function instead of vector<double> as argument x.
I tried to accomplish this with std::variant. The drawback with std::variant is however, that it cannot handle references so the vector x has to be copied while being passed as a variant to the function.
For now I solved the problem by defining two functions with overloaded arguments. But I wonder whether there is a more elegant solution which won't duplicate the code for the two cases (x as double or as vector<double>).
One possible solution might be to define the "worker" function such that it is independent of the "number of passed doubles". For this purpose, std::span
is suitable. The exemplary solution might look like:
std::vector<double> CalcDWorker(
std::span<const double> y, std::span<const double> x)
{
... // x.size() == 1 indicates uniform spacing
}
std::vector<double> CalcDerivative(
const std::vector<double>& y, const std::vector<double>& x)
{
return CaclDWorker({y.begin(), y.end()}, {x.begin(), x.end()});
}
std::vector<double> CalcDerivative(
const std::vector<double>& y, double x)
{
return CaclDWorker({y.begin(), y.end()}, {&x, 1});
}
It requires C++20, but there are third-party span
implementations available also for earlier C++ versions (such as the one provided by Boost).
Live demo: https://godbolt.org/z/n6adEKWes