我知道虚函数不能模板化,但是有没有一种方法可以让派生类实现泛型函数,并且虚函数要求这样的泛型函数具有至少某些参数?我提供了两个例子,第一个是简化的例子,第二个是我想做的事情的更现实的动机(我是一个 C++ 初学者,所以我的想法可能会偏离)。
简化:
class Base
{
public:
template<class T>
virtual T foo(T a, T b, ...) = 0;
};
class DerivedSimple : public Base
{
public:
// Meets the minimum argument requirements in the Base class
template<class T>
T foo(T a, T b) override;
};
class DerivedExtended : public Base
{
public:
// Has the minimum required args AND an arg specific to this class
template<class T>
T foo(T a, T b, int some_special_argument) override;
};
扩展:
#include <Eigen/Core>
#include <Eigen/Sparse>
class SmootherBase
{
public:
/**
* @brief Derived types must implement a `smooth` function that smooths `Au = b`.
*
*/
template <class T>
virtual Eigen::Matrix<T, -1, 1> smooth (
const Eigen::SparseMatrix<T>& A, // <--|
const Eigen::Matrix<T, -1, 1>& u0,// |
const Eigen::Matrix<T, -1, 1>& b, // | must have these args
const size_t niters, // <--|
... // optional args for different smoother
) = 0;
};
class SuccessiveOverRelaxation : public SmootherBase
{
private:
public:
template <class T>
Eigen::Matrix<T, -1, 1> smooth (
const Eigen::SparseMatrix<T>& A, // <--|
const Eigen::Matrix<T, -1, 1>& b, // | The required arguments
const Eigen::Matrix<T, -1, 1>& u0,// |
const size_t niters, // <--|
const float omega // An argument specific to this smoother
) override;
};
class Jacobi : public SmootherBase
{
private:
public:
template <class T>
Eigen::Matrix<T, -1, 1> smooth (
const Eigen::SparseMatrix<T>& A, // <--|
const Eigen::Matrix<T, -1, 1>& u0,// |
const Eigen::Matrix<T, -1, 1>& b, // | The required arguments
const size_t niters, // <--|
) override;
};
您无法覆盖具有不同签名的函数。如果您将这些额外参数发送给类纯粹是为了影响其行为(例如配置选项),那么请考虑更改您的方法,以便在构造函数中提供它们并在
foo()
中使用它们。
正如您已经提到的,您无法模板化虚拟功能。所以奇怪的是你在你的例子中完全这样做了。
这是我上面描述的方法:
template<class T>
class Base
{
public:
virtual T foo(T a, T b, ...) = 0;
};
template<class T>
class DerivedSimple : public Base<T>
{
public:
T foo(T a, T b) override;
};
template<class T>
class DerivedExtended : public Base<T>
{
public:
DerivedExtended(int some_special_argument)
: some_special_argument(some_special_argument)
{}
T foo(T a, T b) override;
protected:
int some_special_argument;
};