0

テンプレート関数を特殊化する方法は知っていますが、ここでやりたいことは、特定のメソッドを持つすべての型の関数を特殊化することです。

template<typename T> void foo(){...}

template<typename T, if_exists(T::bar)>void foo(){...}//always use this one if the method T::bar exists

私のクラスの T::bar は静的で、さまざまな戻り値の型があります。

クラスが派生する空の基本クラス ("class HasBar{};") を用意し、「特殊化された」バージョンで boost::enable_if と boost::is_base_of を使用して、これを実行しようとしました。ただし、問題は、バーがあるクラスの場合、コンパイラーがどちらを使用するかを解決できないことです:(。

template<typename T>
typename boost::enable_if<boost::is_base_of(HasBar, T>, void>::type f()
{...}

「通常の」バージョンでboost::disable_ifを使用できることは知っていますが、通常のバージョンは制御しません(サードパーティのライブラリによって提供され、特殊化が行われることが予想されますが、本当にしたくありません20 ほどのクラスに明示的な特殊化を行う必要があります)、これらの関数を使用するコードをそれほど制御することはできません。T::bar を実装するクラスとそれを使用する関数だけです。

他のバージョンを変更せずに、コンパイラに「可能であれば常にこのバージョンを使用する」ように指示する方法はありますか?

編集:テンプレートクラスと明示的な特殊化を使用して別のアプローチを試みましたが、これも明らかに許可されていません...とにかくこのアプローチを機能させるには?

template<typename T>class ImpFoo
{
public:
    //error C3637: 'foo' : a friend function definition cannot be a specialization of a function template
    template<> friend void foo<T>(){...}
};
...
class SomeClass : public ImpFoo<T>
{
...
    SomeType bar(){...}
};
4

1 に答える 1

2

悲しいことに、説明されているように、この状況では運が悪いです。@aaa が言うように、テンプレートを明示的に特化することが最善の方法です。
これらの特殊化を 1 つの中央関数への単純な転送に制限できるため、20 クラスのオーバーヘッドは耐えられるはずです。例えば:

template<class T> my_foo() { /* do the actual work */ }

template<> void foo<MyClass01>() { my_foo<MyClass01>(); }
// ...
template<> void foo<MyClass20>() { my_foo<MyClass20>(); }
于 2010-05-23T01:39:04.810 に答える