具有*至少*某些参数的模板和虚函数

问题描述 投票:0回答:1

我知道虚函数不能模板化,但是有没有一种方法可以让派生类实现泛型函数,并且虚函数要求这样的泛型函数具有至少某些参数?我提供了两个例子,第一个是简化的例子,第二个是我想做的事情的更现实的动机(我是一个 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;
};
c++ oop templates
1个回答
0
投票

您无法覆盖具有不同签名的函数。如果您将这些额外参数发送给类纯粹是为了影响其行为(例如配置选项),那么请考虑更改您的方法,以便在构造函数中提供它们并在

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;
};
© www.soinside.com 2019 - 2024. All rights reserved.