@Nawazが示すように、リゾルバータイプでディスパッチするのが最善の方法です。別のオプションは、その関数の実際の実装をクラスの外、独自の構造体内に移動し、静的にし、構造体を部分的に特殊化することです。クラス内で、それを呼び出します。もちろん、 のプライベートな部分にアクセスする場合は、次のmyClass
ようにする必要がありますfriend
。
template<class A, class B, class C>
class myClass;
template<class A, class B, class C>
struct myClassFuncs{
typedef myClass<A,B,C> class_type;
static void myFunc(class_type* self){
// generic for everything ...
}
};
template<class A, class B>
struct myClassFuncs<A,B,int>{
typedef myClass<A,B,int> class_type;
static void myFunc(class_type* self){
// specialized on C == int ...
}
};
// and so on ...
template<class A, class B, class C>
class myClass{
typedef myClassFuncs<A,B,C> func_holder;
friend class func_holder;
public:
void myFunc(){
func_holder::myFunc(this);
}
};
それはクラスと特殊化されたバージョンの多くのラッパーにつながりますが...
かなりクレイジーとも言えるもう 1 つのアイデアは、クラスに関数ではなくファンクターを持たせることです。それらは特殊化されてから呼び出されます。これはより冗長ですが、特化したい関数へのより良いアクセスを可能にします。ただし、プライベート パーツにアクセスしたい場合は、すべてのユーザーを友達にする必要があります。:/
template<class A, class B, class C>
class myClass;
template<class A, class B, class C>
class myClass_myFunc{
typedef myClass<A,B,C> class_type;
class_type* const _self;
public:
myClass_myFunc(class_type* self)
: _self(self)
{}
void operator() const{
// generic logic here
}
};
template<class A, class B>
class myClass_myFunc<A,B,int>{
typedef myClass<A,B,int> class_type;
class_type* const _self;
public:
myClass_myFunc(class_type* self)
: _self(self)
{}
void operator() const{
// specialized logic here
}
};
template<class A, class B, class C>
class myClass{
friend class myClass_myFunc<A,B,C>;
public:
myClass()
: myFunc(this)
{}
const myClass_myFunc<A,B,C> myFunc;
};