【发布时间】:2020-03-12 16:24:21
【问题描述】:
我目前正在尝试编写一个微分方程求解器,并希望将类用作运算符,它定义了一个重载的 operator() 以便我可以将运算符用作函子。目标是我有一些数据,为了表示温度的参数,让我们取 T,我想提供一个像 ddt(T) == laplacian(T) 这样的接口,其中 ddt 是关于的一阶偏导数时间,拉普拉斯算子是关于空间的二阶偏导数。在这个例子中,我只是求解一个热方程。
由于我想允许不同的时间和空间方案,我想有两个时间和空间基类,然后从这些基类派生出近似时间或空间的数值方案,其中我的 operator() 是定义为纯虚函数。
我希望能够从它的operator()返回一个空间运算符的引用,所以我使用CRTP在基类中指定返回类型。
时间运算符位于等式的左侧,应该处理右侧的所有信息。因此,在时间类中定义的 operator== 从右侧接收一个运算符。 问题出在这里: operator== 的参数要求我指定要传入的右侧运算符的类型,但是我不知道应该使用哪种类型模板参数,因为我想稍后接受不同类型的运算符。鉴于下面的代码,有没有一种干净的方法来解决这个问题?
#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;
}
【问题讨论】:
-
从数学上讲,
ddt(T)和laplacian(T)纯粹是 T 的 函数。所以我想挑战您的第一个陈述,即您“想将类用作运算符” .您将这些操作实现为对象的实例而不仅仅是函数的理由是什么?为什么你的spaceOperatorBase需要拥有一个向量而不是作为另一个参数?您可以将函数签名定义为一种类型,因此ddt(T)和laplacian(T)的所有各种实现仍然可以“继承”一个通用函数签名。 -
好吧,这是一个适用于本网站的玩具示例,显然看看这个简单的示例您可能有一点意思。但是,对于我的实际问题,我确实有理由想要使用函子,该函子直接对他们不拥有的数据进行操作(所以我最终不会得到同一个操作符的多个实例,其中只有它操作的数据发生变化)我有充分的理由想要将对象传递给时间运算符,这需要来自空间运算符的一些信息,因此只传递整个对象会更简单。但同样,在不知道类型的情况下,我不知道如何
标签: c++ templates polymorphism crtp