是否可以仅为类的特定模板实例声明成员函数?这就是我想要这样做的原因:
// Polynomial<N> is a polynomial of degree N
template<int N>
class Polynomial {
public:
//... various shared methods e.g...
double eval(double x) const;
Polynomial<N-1> derivative() const;
Polynomial<N+1> integralFrom(double x0) const;
// ... various shared operators etc.
double zero() const; // only want Polynomial<1> to support this
// only want Polynomial<2> and Polynomial<1> to support the following
// because the solutions rapidly become too difficult to implement
std::vector<double> zeros() const;
std::vector<double> stationaryPoints() const { return derivative().zeros();}
private:
std::array<double,2> coeffs;
}
我目前的解决方法是从Polynomial<N>::zeros()
为N>2
抛出异常,但在编译时检测问题会很好。
答案 0 :(得分:1)
您也可以使用std::enable_if
远离SFINAE零功能。
template< int I >
class Poly {
public:
template<int Ib = I, typename = std::enable_if_t<Ib == 1> >
double zero()
{
return 42;
}
};
int main()
{
Poly< 10 > does_not_compile;
does_not_compile.zero();
//Poly< 1 > compile;
//compile.zero();
}
答案 1 :(得分:0)
您的解决方案是模板专业化,在本例中是完全专业化。
但是,我认为你需要考虑你的设计。通常,为不同的情况定义不同的接口并不是一个好主意,因为你没有利用抽象。
例如,考虑一下你的stationaPoints()函数。 Polynomial&lt; 2&gt;不能使用此功能。因为衍生物是多项式&lt; 1&gt;。它没有zeros()函数。您的解决方案是将零函数添加到多项式&lt; 1&gt;。为了使界面均匀化。
对于你的情况,我想你想要一个解决方案,其中包含多项式类型中的N-1 c向量,其中零和零(i)函数可以得到它们。像这样:
template <int N>
class Polynomial {
double _coefs[N+1];
double _zeros[N];
public:
double zero(size_t i) const { assert(i<N); return _zeros[i]; }
// ...
};
在这种情况下,你可以决定计算de zeros的策略,具体取决于你的应用程序:constructor ?,添加一个布尔值来知道它是否已经计算,然后在第一次调用零时计算,等等......
我想这个解决方案对你来说可能更有趣,因为如果你更喜欢使用c-vector来存储系数,你不会喜欢你的zeros()函数的基于矢量的接口,不是吗?
答案 2 :(得分:0)
您可以使用CRTP在知道派生类的基类中实现zeros
和zero
。
然后有条件地从具有zeros
和/或zero
的人那里派生。
template<class P>
struct zeros { /* todo */ };
template<class P>
struct zero:zeros<P> { /* todo */ };
struct nozero {};
template<int N>
struxt Polynomial:
std::conditional_t<
(N==1),
zero<Polynomial<N>>,
std::conditional_t<
(N==2),
zeros<Polynomial<N>>,
nozero
>
>
{
// body
};