根据模板参数添加成员函数和成员变量

时间:2019-03-01 20:53:59

标签: c++ templates c++17 sfinae template-specialization

我有一个函数族{f_n},其中f_0是连续的,f_1是连续可微的,$ f_ {n} \ in C ^ {n} [a,b] $以此类推。我有一个C ++类,该类通过向量f_n上的查找表对v进行数值评估

template<int n, typename Real=double>
class f
{
public:
    f() { /* initialize v */ }

    Real operator()(Real x) { /* find appropriate index for x, and interpolate */}

private:
    std::vector<Real> v;
};

但是,如果f是可区分的(n >= 1),我想添加一个成员函数:

template<int n, typename Real=double>
class f
{
public:
    f() { /* initialize v and dv */ }

    Real operator()(Real x) { /* find appropriate index for x, and interpolate on v */}

    Real prime(Real x) { /* find appropriate index for x, and interpolate on dv */}

private:
    std::vector<Real> v;
    std::vector<Real> dv;
};

我还想为n> = 2添加第二个导数成员,依此类推。 可以在一个班上完成吗? (我可以接受C ++ 17语法。)

2 个答案:

答案 0 :(得分:4)

对于每个n > 0,我们添加一个新的成员函数,将该值作为从下一级继承的参数:

template<int n, typename Real=double>
class f
    : public f<n-1, Real>
{
public:
    f() { /* initialize dv */ }

    using f<n-1, Real>::prime;
    Real prime(Real x, integral_constant<int, n>) { 
        /* find appropriate index for x, and interpolate on dv */
    }

protected:
    std::vector<Real> dv;
};

基本版本在其中添加operator()的地方:

template<typename Real=double>
class f<0, Real>
{
public:
    f() { /* initialize v */ }

    Real operator()(Real x) { /* find appropriate index for x, and interpolate */}
    Real prime(Real x) { return (*this)(x); }

protected:
    std::vector<Real> v;
};

这意味着一阶导数调用prime(x, integral_constant<int, 1>{}),二阶导数调用prime(x, integral_constant<int, 2>{}),等等。

答案 1 :(得分:1)

您可以简单地拥有一个模板成员函数和一个static_assert,以确保您不会使用类不支持的派生类。例如:

template <int n, /* other stuff */>
class f
{
  /* Other stuff not shown */
  template <int p>
  Real prime(Real x)
  {
    static_assert(p <= n, "unsupported derivative");
    /* do whatever you need to to implement the pth derivative */
  }
};

因此,类型为f <1>的对象将支持prime <1>(),但不支持prime <2>(),依此类推。如果不小心在类型为f <1>的对象上调用prime <3>会叫你出来的。由您决定是否要将prime<0>等同于operator ()或更改您的static_assert以包括对p > 0的检查。