2013-03-20 5 views
7

私が考えているアプリケーションは、私が唯一の大きさは、私はそれを回避ハックすることができます方法があります知っている3のときのためにテンプレートクラスの特異なインスタンス化に属する関数を宣言できますか?

CrossProduct(const Vector<size>& other) 

を宣言したいでVector<size>クラスに似て何かを、...

です
  • のみサイズ= 3
  • のための関数定義を含め、すべての他のサイズは、リンカエラーを得ましょう
  • は、サイズが3
  • であるかどうかを確認する方法の開始時に静的アサートを実行します。

特定のインスタンス化に対してメンバー関数を適切に宣言する方法はありますか?

+1

あなたはコンパイル時のサポートを探している、または実行時エラーがあなたのニーズを満たす生成するのでしょうか? – Porkbutts

答えて

5

ここでそれを行うための一つの方法です:

template <class Type, size_t Size> 
struct EnableCrossProduct 
{ 

}; 

template <class Type> 
struct EnableCrossProduct<Type, 3> 
{ 
    void CrossProduct(const Type & other){} 
}; 

template <size_t Size> 
struct Vector : public EnableCrossProduct<Vector<Size>, Size> 
{ 
}; 
+2

楽しみを繰り返す '何でも'。 – GManNickG

+0

私は、1つまたは2つの機能を追加するために、クラス全体を書き直すのではなく、 –

+1

@GManNickG行くよ、固定 –

3

コンパイル時にサイズ情報を取得できる場合は、std :: enable_ifを使用できます。

template<int N> 
struct Vector 
{ 
    static const int size = N; 
    double data[N]; 
    // ... 

    template<class V> 
    double CrossProduct(const V& other, 
     typename std::enable_if< size == 3 && V::size == 3 >::type* = 0) const 
    { 
     // ... 
     return 0; 
    } 
}; 

void foo(const Vector<3>& v3, const Vector<4>& v4) 
{ 
    v3.CrossProduct(v3); // Ok 
    v3.CrossProduct(v4); // Compile-time error 
} 

あなただけenable_if size == V::sizeにその状態を作りたいかもしれません。

+0

'CrossProduct(v3)と' CrossProduct(v4) 'はコンパイル時エラーです...これはメンバ関数です。 –

+0

2番目のSFINAEの例が正しくありません。たとえば、 'CrossProduct'を使わなくても、' Vector <4> 'の単なるインスタンス化に失敗します。また、特殊化とは、情報を繰り返すこと(「// ...」)またはそれを分解することを意味します。 – GManNickG

+0

両方の問題を修正しました。 – metal

2

static_assertの方法を好むでしょう。

  • SFINAE
  • ための最も簡単な方法である必要がないので、この

    • 明確なエラーメッセージ
    • につながるが適当です。
    +1

    ええ...いいですが、Visual StudioのItellisenseを汚染するのは残念です。マイナーな苦情、私は知っているが、それは私の目的のためにクラスのユーザビリティに少し影響する。 –

    +0

    Intellisense(私のような)をコードしていない人がいます。彼らがあなたのコードを使用している場合は、あなたも同様に考える必要があります。 – ipc

    +1

    理想的には、私は両当事者のニーズに合った解決策を見つけるでしょう。それは起こりそうもないようだ。それは尋ねることを傷つけませんでした=) –

    関連する問題