Реализовать математический вектор в C++ с повторным использованием контейнеров стандартной библиотеки
Этот вопрос вызван следующей реализацией формулы Рунге-Кутта для интегрирования обыкновенных дифференциальных уравнений первого порядка (ОДУ).
template <typename Field, typename Vector>
auto
runge_kutta(const Vector& y,
std::function<Vector(Field, const Vector&)> rhs,
Field t, Field delta_t)
{
Vector k1 = rhs(t, y);
Vector k2 = rhs(t + delta_t/2, y + delta_t/2*k1);
Vector k3 = rhs(t + delta_t/2, y + delta_t/2*k2);
Vector k4 = rhs(t + delta_t, y + delta_t * k3);
return y + delta_t/6*(k1 + 2*k2 + 2*k3 + k4);
}
Это может быть использовано для интеграции таких функций, как следующие
double f(double t, double y) { return y; }
Но приведенный выше код Рунге-Кутты также можно использовать для решения ОДУ более высокого порядка или ОДУ более чем с одной зависимой переменной. Для этого параметр шаблона Vector должен быть контейнером чисел (или векторов другого типа) с соответствующим образом определенными арифметическими операторами.
Поэтому ищу реализацию типа для Vector
со следующими свойствами:
- Тип - это контейнер чисел или векторов различного типа.
- Соответственно перегруженные операторы
operator+
,operator-
,operator*
а такжеoperator/
. - Для использования этих операторов не требуется объявление using в вызывающем коде.
- Стандартная библиотека используется повторно.
Лучшее, что я придумал, - это создать операторы для std::array
в новом пространстве имен
namespace Stackru {
template<typename Field, typename Element, std::size_t Dim>
auto
operator*(Field lhs, const std::array<Element, Dim>& rhs);
// etc., etc.
}
и иметь подходящее объявление using в вызывающем коде (нарушение пункта 2 выше)
using Stackru::operator+; ...
Другая возможность - публично извлечь изstd::array
. Это работает, но, как я узнал, это явно запрещено стандартом языка C++.
Можно ли повторно использовать std::array
- сохранение первых четырех свойств выше - без перезаписи std::array
полностью?