2017-04-04 4 views
1

私の問題の定義で始めることができます:複雑で畳み込まれたテンプレート

私は一度だけ定義したいと思う超大型スイッチ文を持っています。これは完璧に動作

switch(whatever) 
{ 
    case whatever::one: 
     dosomething<char>(parameterone, parametertwo); breakl 
    case whatever::two: 
     dosomething<int>(parameterone, parametertwo); break; 
    ... 
} 
} 

:switch文の各ケースは、その後

はすなわち、テンプレート関数を呼び出します。しかし、私は物事を複雑にしたいと言うことができます。具体的には、case文が2つの関数を呼び出すようにします。

すなわち:Fは、関数ポインタのいくつかの並べ替えである

template<typename F> 
void wrapper(parameterone, parametertwo) 
{ 
    switch(whatever) 
    { 
    case whatever::one: 
     F<char>(parameterone, parametertwo); break; 
    case whatever::two: 
     F<int>(parameterone, parametertwo); break; 
    ... 
    } 
} 
} 

。はい:(I本当にDONT F FOR EVERY VALID関数のswitch文を複製する注)

+0

テンプレート引数を 'wrapper'に渡したいものを制御できますか? – Angew

答えて

2

wrapper<dosomething>(...); 

OR

wrapper<superdosomething>(..); 

:それから私はこのような何かラッパー関数を呼び出しますそのようなラッパーを書くことができます。私はあなたの実際のコードに基づいて適合させる必要があるかもしれない代表団の層を使用します。

template <class F> 
void wrapper(param1, param2) 
{ 
    switch (whatever) 
    { 
    case whatever::one: 
     F::call<char>(param1, param2); 
     break; 

    case whatever::two: 
     F::call<int>(param1, param2); 
     break; 
    } 
} 


struct DoSomething 
{ 
    template <class T> 
    static void call(param1, param2) { /* your code */ } 
}; 


struct DoSomethingSuperCool 
{ 
    template <class T> 
    static void call(param1, param2) { /* your super-cool code */ } 
}; 

使用法:

wrapper<DoSomething>(p1, p2); 
wrapper<DoSomethingSuperCool>(p1, p2); 
0

ほとんど確かにあなたは関数としてではなく、クラスとしてFを持っている必要はありません。そのようなクラスは、おそらく部分的または完全に特殊化されたテンプレートクラスである可能性があります(関数よりもクラスの特殊化を行うほうがはるかに簡単です)。

その他の詳細は不明です。クラスには、静的関数の束を持つことができます。 ProcessOne、ProcessTwoなどを特定のswitch節で呼び出すことができます。クラスに状態がある場合、それらは非静的でなければならず、仮想でもなければなりません。実装の継承は、コードを比較的コンパクトにすることを可能にします。

通常、巨大なswitch文は、あまり良くない設計の指標であり、多くの場合、他のタイプのディスパッチで置き換えることができます。仮想関数を使用します。

関連する問題