2011-02-07 11 views
3

私は現在、いくつかのコードをリファクタリングしています.2つのテンプレートパラメータを持つクラステンプレートのメンバ関数を明示的に特化しています。 部分的に特化したメンバ関数の実装

template <class S, class T> 
class Foo 
{ 
    void bar(); 
}; 

template <class S, class T> 
void Foo<S, T>::bar() 
{ /* Generic stuff */ } 

template <> 
void Foo<SomeType, SomeType>::bar() 
{ /* Some special function */ } 

は今、私はいくつかのより多くのテンプレートパラメータを追加し、そのクラスには次のようになります。

template <class S, class EXTRA0, class T, class EXTRA1> 
class Foo 
{ 
    void bar(); 
}; 

ランタイム機能はないので、これら2つの追加のパラメータはちょうど、私のクラスに型定義を追加本当に変わる。私は棒の(今は部分的に)特殊化された実装を保つことができる方法はありますか?私はそれの構文を理解しているように見えることはできませんし、私はそれが可能ではないかもしれない愚直さがあります。

編集:は私のようなものを探しています:コンパイルしていないよう

template <class EXTRA0, class EXTRA1> 
void foo<SomeType, EXTRA0, Sometype, EXTRA1>::bar() 
{ 
    /* specialized implementation */ 
} 

..あなたが正しい

+1

私の知る限りでは、あなたが右に覚えている:あなたは、部分的に機能し、型のみを専門とすることはできません。 – Simone

+0

@Simoneそれは少なくともg ++で動作しています。 – UmmaGumma

+0

私の4.5.0バージョンの@Ashotはコンパイルされません。http://codepad.org/q6CVktqyを参照してください。 – Simone

答えて

3

は、それは不可能です。

あなたができることは、新しいFooの内部にヘルパーメンバクラステンプレートを作成し、その中に特別な機能をテンプレート以外のメンバ関数として配置することです。関数の代わりにヘルパークラスを特化します。

また、特殊化をテンプレート以外の過負荷にすることもできます。

1

私はあなたが望むものは簡単に可能だとは思わない。

template <class S, class EXTRA0, class T, class EXTRA1> 
class FooBase 
{ 
    void bar(); 
}; 

template <class S, class EXTRA0, class T, class EXTRA1> 
void FooBase<S, EXTRA0, T, EXTRA1>::bar() 
{ /* Generic stuff */ } 

template <class S, class EXTRA0, class T, class EXTRA1> 
class Foo 
    : public FooBase <S, EXTRA0, T, EXTRA1> 
{ }; 

template <class EXTRA0, class EXTRA1> 
class Foo<int, EXTRA0, int, EXTRA1> 
    : public FooBase <int, EXTRA0, int, EXTRA1> 
{ 
    void bar(); 
}; 

template <class EXTRA0, class EXTRA1> 
void Foo<int, EXTRA0, int, EXTRA1>::bar() 
{ /* Some special function */ } 
1

あなたがバーを除いて、すべてのメンバーを定義することができます基本クラスを、()を作成し、その後、派生クラス(一般的な目的のために1、SomeTypeに1つ)を作成することができます:

template <class S, class T> 
class FooBase 
{ 
     // All other members 
}; 

template <class S, class EXTRA0, class T, class EXTRA1> 
class Foo:public FooBase<S,T> 
{ 
public: 
     void bar() 
     { 

     } 
}; 

struct SomeType {}; 

template <class EXTRA0, class EXTRA1> 
class Foo<SomeType,EXTRA0,SomeType,EXTRA1>:public FooBase<SomeType,SomeType> 
{ 
public: 
    void bar() 
    { 

    } 
}; 

int main() 
{ 
    Foo<SomeType,int,SomeType,int> b; 
    b.bar(); 
} 
をこのようなものについては何
1

代わりに機能を特化ファンクタを使って、それを達成することができます

#include <iostream> 

typedef int SomeType; 

template <class A, class B> 
class BarFunctor { 
public: 
    void operator()() { 
     std::cout << "generic" << std::endl; 
    } 
}; 

template <> 
class BarFunctor<SomeType, SomeType> { 
public: 
    void operator()() { 
     std::cout << "special" << std::endl; 
    } 
}; 

template <class S, class T, class EXTRA0, class EXTRA1> 
class Foo { 
public: 
    void helloWorld() { 
     std::cout << "hello world !" << std::endl; 
    } 

    void bar() { 
     return _bar(); 
    } 

private: 
    BarFunctor<S, T> _bar; 
}; 

int main() { 

    Foo<char, char, char, char> gen; 
    Foo<SomeType, SomeType, char, char> spe; 
    gen.helloWorld(); 
    spe.helloWorld(); 
    gen.bar(); 
    spe.bar(); 
    return 0; 
} 
+0

また、あなたがFooと対話する必要がある場合は、Visitorを使用してください... – Errata

関連する問題