根据模板参数添加成员函数和成员变量
Add member functions and member variables based on template argument
我有一个函数族 {f_n}
其中 f_0
是连续的,f_1
是连续可微的,$f_{n} \in C^{n}[a,b ]$等等。我有一个 C++ class,它通过对向量 v
的查找 table 给出 f_n
的数值评估
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 添加二阶导数,依此类推。
这可以在单个 class 中完成吗? (C++17 语法对我来说是 acceptable。)
对于每个 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>{})
,等等
您可以简单地拥有一个模板成员函数和一个 static_assert,以确保您不会使用 class 不支持的导数。例如:
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
.
的检查
我有一个函数族 {f_n}
其中 f_0
是连续的,f_1
是连续可微的,$f_{n} \in C^{n}[a,b ]$等等。我有一个 C++ class,它通过对向量 v
f_n
的数值评估
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 添加二阶导数,依此类推。 这可以在单个 class 中完成吗? (C++17 语法对我来说是 acceptable。)
对于每个 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>{})
,等等
您可以简单地拥有一个模板成员函数和一个 static_assert,以确保您不会使用 class 不支持的导数。例如:
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
.