Этот вопрос мотивирован следующей реализацией формулы Рунге-Кутта для интегрирования обыкновенных дифференциальных уравнений (ОДУ) первого порядка.
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 должен быть контейнером чисел (или векторов другого типа) с соответствующим образом определенными операторами arithmeti c.
Поэтому я ищу реализацию типа для Vector
с следующие свойства:
- Тип представляет собой контейнер чисел или различных типов векторов.
- Соответствующим образом перегруженные операторы
operator+
, operator-
, operator*
и operator/
. - Отсутствие объявления using в вызывающем коде, необходимого для использования этих операторов.
- Повторно используется стандартная библиотека.
Лучшее, что я придумал, это чтобы создать операторы для std::array
в новом пространстве имен
namespace StackOverflow {
template<typename Field, typename Element, std::size_t Dim>
auto
operator*(Field lhs, const std::array<Element, Dim>& rhs);
// etc., etc.
}
и иметь подходящее объявление using в вызывающем коде (нарушение пункта 2 выше)
using StackOverflow::operator+; ...
Другая возможность - получить публично от std::array
. Это работает, но, как я узнал, это явно запрещено стандартом языка C ++.
Можно ли повторно использовать std::array
- с сохранением первых четырех свойств выше - без полного переписывания std::array
?