2009-10-08 23 views
10

テンプレートクラスメソッドの部分的な特殊化はありますか?C++部分メソッドの特殊化

template <class A, class B> 
class C 
{ 
    void foo(); 
} 

それはこのようにそれを専門に動作しません:

template <class A> void C<A, CObject>::foo() {}; 

任意のヘルプ?

+0

他の回答にはいくつかの方法があります:http://stackoverflow.com/questions/1501357/template-specialization-of-particular-members/1501455#1501455 –

答えて

11

あなたはすでにあなたが専門のクラスでfooの異なる実装を与えることができるクラスを特化している場合:

template<typename A, typename B> 
class C 
{ 
public: 
    void foo() { cout << "default" << endl; }; 
}; 

template<typename A> 
class C<A, CObject> 
{ 
public: 
    void foo() { cout << "CObject" << endl; }; 
}; 

メンバ関数を特化するためにあなたはそれがあまりにもテンプレート作ることができるのVisual C++ 2008で:

template<typename A, typename B> 
class C 
{ 
    template<typename T> 
    void foo(); 

    template<> 
    void foo<CObject>(); 
}; 

上記の解決策は、将来のC++標準でのみ使用可能になるようです(ドラフトn2914 14.6.5.3/2 )。

+0

2番目が間違っていますが、最初は間違っています - クラススコープに明示的な特殊化を加えることはできません - テンプレートの特殊化を名前空間スコープに入れても - テンプレートを専門にするならば、あなたは2番目の方法に固執しなければなりません。 –

+0

これは、例えば、テンプレートテンプレート<> void C :: foo (){} 'のように動作しません。メンバ関数のテンプレートは特殊化されていますが、外側のテンプレートはまだありません。テンプレート<テンプレート>の代わりに他の方法を使うことができます。 void C :: foo(){} 'しかし、 to -.- –

+0

最初はC++ 03標準に準拠していないようですが、Visual C++ 2008で動作します。C++ 0x拡張(14.6.5.3クラステンプレートのメンバーライゼーション)。 –

1

クラスはテンプレートなので、あなたはそれを専門にする必要があります。

template <class A> 
class C<A, CObject> 
{ 
    void foo() { ... } 
} 
+0

私はすでに専門クラスですが、 specialize method :) – faya

0

私の記憶が正しければ、あなたは機能のためのテンプレートの部分特殊化をすることはできません。それはC++ 0Xに含まれているかどうかわからない

更新:コメントで述べたように (待ち確認) 、機能のテンプレートの部分特殊化は、C++ 0Xで可能です。

+0

この制限はC++ 0x –

+0

@yngvedhで解除されています。この「更新:」メモの参照はありますか?私はこれについてまだ聞いていない。 Afaik、彼らはデフォルトの議論を取り戻しました - つまり、あなたは関数テンプレートにデフォルトの引数を持つことができます。 –

+0

@libt、参照はありません。私はちょうどthe_drowが私がC++ 0Xの専門家ではないので、彼が何を話しているかを知っていたと仮定しました。知っている人は誰でもこれを確認できますか?私は適切に更新します。 –

8

そこには誤解があると思います。

テンプレートの2種類があります

  • テンプレートクラス
  • あなたの例では、テンプレートメソッド

が、あなたはもちろん、いくつかのメソッドが含まれているテンプレートクラスを、持っています。この場合、クラスを専門化する必要があります。

template <class A> 
class C<A,CObject> 
{ 
    void foo() { ... } // specialized code 
}; 

あなたの例では問題は比較的簡単です:あなたは専門のC用メソッドfooを定義が、この専門分野は、あらかじめ宣言されていません。

ここで問題となるのは、Cクラスを完全に特殊化しなければならないことです(したがって、大量のデータをコピーする必要があります)。いくつかの回避策があります。

  • 継承(Composition?):基本クラスのすべての一般的な作業を行い、Cクラスを継承して適切に特化します。
  • フレンド: 'foo'メソッドをCのメンバーにする代わりに、フレンドリーな関数として定義してspecializeしますこの方法のみ
  • 委任:あなたの「FOO」メソッドはフリー機能である別の方法「バー」を、呼び出し、適切

コードに与える「バー」を専門としています

// 1- Inheritance 
template <class A, class B> 
class CBase 
{ 
    // Everything that does not require specialization 
}; 

template <class A, class B> 
class C: public CBase<A,B> 
     // depending on your need, consider using another inheritance 
     // or even better, composition 
{ 
    void foo(); // generic 
}; 

template <class A> 
class C<A,CObject> : public CBase<A,CObject> 
{ 
    void foo(); // specialized 
}; 

// 2- Friend 
// note the change in signature: 
// - now you need to pass the attributes to be changed 
// - the last parameter helps differentiating the overload 
// as there is no specialization for functions 
template <class A, class B> void foo(Arg1&, Arg2&, const B&); 
template <class A> void foo(Arg1&, Arg2&, const CObject&); 

template <class A, class B> 
class C 
{ 
    friend template <class, class> foo; 
}; 

// 3- Delegation 
// same signature as foo in (2) 
template <class A, class B> void bar(Arg1&, Arg2&, const B&); 
template <class A> void bar(Arg1&, Arg2&, const CObject&); 

template <class A, class B> 
class C 
{ 
    void foo() { bar(member1, member2, B()); } 
}; 

それが明確になり、助けてくれることを願っています!

2

いいえ、追加されるC++ 0xには部分関数テンプレートの特殊化はありません。 ;

  • デフォルトのテンプレート引数が使用可能になりました:として正しく基本的に2つのことが行われた関数テンプレートに関して、上記

  • 可変性テンプレートを導入した。

これまでのように、部分的な関数テンプレートの特殊化を「エミュレートする」には回避策を使用する必要があります。

関連する問題