2016-07-13 6 views
0

クラスの特定のテンプレートインスタンス化に対してのみメンバー関数を宣言できますか?私はそれをしたい理由はここにある:クラスの特定のテンプレートインスタンス化のメンバー関数のみを宣言する

// 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; 
} 

私の現在の回避策はただN>2ためPolynomial<N>::zeros()から例外をスローすることですが、コンパイル時に問題を検出するために、素敵だったでしょう。

+0

テンプレートの特殊化は可能ですか? – Pumkko

+0

C++ 11が利用できる場合、 'static_assert(N <= 2、"不正なテンプレート引数 ")'を 'throw'の代わりに使用することができます。コンパイル時に望ましくない機能を防止します。 – ilotXXI

+0

とにかく特殊化が必要です( 'Polynomial 'のため) –

答えて

0

あなたは由来する1つ知っている基底クラスでzeroszeroを実装するためにCRTPを使用することができます。

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 
}; 
0

あなたのソリューションはテンプレートの特殊化です(この場合、完全修飾)。

しかし、私はあなたのデザインについて考える必要があると思います。一般に、抽象化を利用していないため、さまざまなケースに異なるインターフェースを定義することはお勧めできません。

たとえば、stationaPoints()関数について考えてみましょう。この関数は、派生関数がゼロ()関数を持たない多項式< 1>であるため、多項式< 2>では使用できません。あなたの解決策は、インタフェースを均質化するために、ゼロ点関数を多項式<に追加することです。

あなたのケースでは、ゼロを持つ多項式型の中にN-1cベクトルを含み、それらを得るためのゼロ(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]; } 
    // ... 
}; 

、あなたのアプリケーションに応じて、デ・ゼロを計算するための戦略を決めることができました:コンストラクタ?それが最初に計算された後に計算されているかどうかを知るためにブール値を追加します0などの呼び出し...

coeficientsを格納するためにcベクトルが好きなので、このソリューションはあなたのゼロ()関数のベクトルベースのインターフェイスが嫌いです、あなたは?

+0

'Polynomial 'は私の質問ではN次の多項式であり、N + 1個の係数を持っています。あなたの答えを改訂してもよろしいですか? – Museful

+0

また、より良いデザインを提案できますか?私の現在の解決策は、係数の配列を格納します。私はそれを示すために質問を編集します。 – Museful

0

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(); 
} 
+0

これは技術的に不正なプログラムであり、診断は必要ありません。 – Yakk

+0

なぜですか?どのようなルールが壊れていますか? – Pumkko

+0

私は自分の答えを更新しました。上記は良いですか? – Pumkko

関連する問題