2012-02-29 7 views
3

私は、このセットアップを持っている:UがDontUseに設定されている場合このテンプレートメンバー関数はどのように特化しますか?

class DontUse; 

template<class T,class U = DontUse, class V = SomeStandardType> 
class Foo 
{ 
    public: 
    void bar(U &uh); 
}; 

は、私はバーが空の関数になりたいです。他のすべてのケースでは、私はバーにいくつかの実装をして欲しい。私は、この使用して専門分野をやってみましたが、(私は何とか間違っている実現)このコードはコンパイルされません:

template<class T,class V> void Foo<T,DontUse,V>::bar(DontUse &none){} 
template<class T,class U,class V> void Foo<T,U,V>::bar(U &uh) 
{ 
    //do something here 
} 

エラーメッセージがこの(MSVC10)です:

1>path_to_project: error C2244: 'Foo<T,U,V>::bar' : unable to match function definition to an existing declaration 

、それが指します最初のテンプレートの特殊化の行。

これを正しく行うにはどうすればよいですか?それは関連性のミニマリストの一部に減少していますが、

はここで、実際のコードです:あなたは、テンプレートの個々のメンバーを専門とすることはできません

struct DontUse; 

    template<typename Derived, typename Renderer = DontUse, typename TimeType = long> 
    class Gamestate 
    { 
    public: 

     void Render(Renderer &r); 

    }; 

    template<typename Derived, typename TimeType> void Gamestate<Derived, DontUse,TimeType>::Render(DontUse){} 
    template<typename Derived, typename Renderer, typename TimeType> void Gamestate<Derived,Renderer,TimeType>::Render(Renderer &r) 
    { 
     static_cast<Derived*>(this)->Render(r); 
    } 
+0

特化したクラスの定義を投稿できますか? – Nate

+0

@ネイト:はい、私はそれを質問に入れました。 – TravisG

答えて

3

。あなたは、クラス自体を特化する必要があります。

class DontUse; 

template<class T, class V> 
class Foo<T, DontUse, V> 
{ 
   public: 
     void bar(DontUse) 
    { } 
}; 
3

私はちょうどこれを使用することをお勧めします:あなたは本当に空の関数をしたい場合は

#include <type_traits> 

template <class A, class B, class C> 
struct S 
{ 
    void foo(B& b) 
    { 
     static_assert(!std::is_same<U, DontUse>::value, "Bad Boy!"); 
    } 
}; 

または、ちょうど場合に使用します。

#include <type_traits> 

template <class A, class B, class C> 
struct S 
{ 
    void foo(B& b) 
    { 
     if(!std::is_same<U, DontUse>::value) 
     { 
       //all code goes here 
     } 
    } 
}; 
+0

ありがとうございますが、そのようにするのは十分ではありません。重要なのは、ユーザーが実際にレンダリングを行わないDerived をインスタンス化できるようにすることです(サーバーサイドプログラミングの場合など)。私はちょうどユーザーがその機能を実装したままにしておくことができますが、空ですが、私のやり方で行う方が少し快適です。ちなみに、技術的に彼は私の質問にもっと正確に答えて(そのことをいかに特化するか)、コードを書いたので、私はBo Perssonの答えを受け取ります。 – TravisG

+0

@heishe is_sameを使うと、あなたは何でもできます。例外をスローする、別の関数を呼び出す、など私はあなたがここで問題があるとは思わない。 – cooky451

+0

はい、あなたは今何を意味するのか分かります。 void Render(Renderer&r){if(is_same <...> :: value){何もしない} else {デフォルトのもの}}。それでも、私はここでこの質問のフォローアップの質問をしました。コンパイル時にこれがどうなるかは尋ねます:http://stackoverflow.com/questions/9503042/how-do-i-select-an-alternative -member-function-implementation-dependent-on-a-te#comment12033196_9503042 – TravisG

1

このようには機能しません。クラステンプレートのメンバ関数自体は別のテンプレートではなく、クラステンプレートとは独立して(部分的または完全に)特殊化することはできません。

クラステンプレートFooの部分特殊化を定義し、それにbarメンバ関数を与え、それを定義する必要があります。

関連する問題