В настоящее время я пытаюсь написать решатель дифференциальных уравнений и хочу использовать классы в качестве операторов, которые определяют перегруженный оператор (), чтобы я мог использовать операторы в качестве функторов. Цель состоит в том, чтобы у меня были некоторые данные, давайте возьмем T для аргумента, представляющего температуру, и я хочу предоставить интерфейс, такой как ddt (T) == laplacian (T), где ddt - частная производная первого порядка по отношению к время, а лапласиан - частная производная второго порядка по пространству. В этом примере я просто решаю уравнение теплопроводности.
Поскольку я хочу учесть различные схемы времени и пространства, я хочу иметь два базовых класса для времени и пространства, а затем вывести свои числовые схемы, которые приближаются либо время, либо пространство из тех базовых классов, где мой оператор () определен как чисто виртуальная функция.
Я хочу иметь возможность вернуть ссылку на оператор пространства из его оператора (), поэтому я использую CRTP для указания типа возвращаемого значения в базовом классе.
Оператор времени находится в левой части уравнения и должен обрабатывать всю информацию из правой части. Следовательно, оператор ==, определенный во временном классе, получает оператор с правой стороны. Здесь кроется проблема: Аргумент оператора == требует от меня указать тип правостороннего оператора, который я передаю, однако я не знаю, какой тип использовать для Шаблонный аргумент, поскольку я хочу принять различные типы операторов позже. Учитывая приведенный ниже код, есть ли чистый способ обойти эту проблему?
#include <iostream>
#include <vector>
using Vector = std::vector<double>;
template<class Type>
struct spaceOperatorBase {
virtual Type operator()(Vector &data) = 0;
protected:
Vector _data;
};
struct laplacianOperator : public spaceOperatorBase<laplacianOperator> {
laplacianOperator operator()(Vector &data) final override {
std::cout << "solving laplacian operator" << std::endl;
this->_data = data;
return *this;
}
};
template <class Type>
struct timeOperatorBase {
virtual Type operator()(Vector &phi) = 0;
virtual void operator==(const spaceOperatorBase<laplacianOperator> &rhs) = 0; // <- how to get rid here of the dependency on <laplacianOperator>?
};
struct eulerOperator : timeOperatorBase<eulerOperator> {
eulerOperator operator()(Vector &phi) {
std::cout << "preparing time-integration" << std::endl;
return *this;
};
void operator==(const spaceOperatorBase<laplacianOperator> &rhs) { // <- how to get rid here of the dependency on <laplacianOperator>?
std::cout << "solving equation" << std::endl;
};
};
int main() {
Vector T;
laplacianOperator laplacian;
eulerOperator ddt;
ddt(T) == laplacian(T);
return 0;
}