2011-06-03 127 views
3

我有一個關於C++模板專業化的問題,我希望這裏有人能提供幫助。我有一個有3個模板參數類:專門研究C++模板中的子類型

template<class A, class B, class C> 
class myClass { 

public: 
    void myFunc(); 
}; 

我想要做的就是寫myFunc的幾個版本,專門的,比方說,C型,但對於通用類型A和B,所以我不要完全模板函數是這樣的:

template<class A, class B, class C> 
void myClass<A, B, C>::myFunc() 
{ 
    // function code here 
} 

,我不希望這樣的

void myClass<int, int, int>::myFunc() 
{ 
    // code goes here 
} 

完全專業化的功能相反,我想要做的事,這將是類似於

template<class A, class B> 
void myClass<A, B, int>::myFunc() 
{ 
    // code goes here 
} 

的想法是,如果類C型爲int,我會打電話myFunc的(一版),如果類C類是雙重的,我會打電話的不同版本在myfunc。我已經嘗試了很多不同的模板專業化語法的組合(這裏列出了太多),而且似乎沒有編譯。

有人可能在這裏指出我在正確的方向嗎?在此先感謝您的幫助。

邁克爾

回答

6

您可以編寫一個函數模板,過載,而工作委託給它:

template<class A, class B, class C> 
class myClass 
{ 
    //resolver doesn't need to define anything in it! 
    template<class> struct resolver {}; //empty, yet powerful! 
public: 
    void myFunc() 
    { 
     doFun(resolver<C>()); 
    } 

    //this is a function template 
    template<typename X> 
    void doFun(const resolver<X> &) 
    { 
     //this function will get executed when C is other than int 
     //so write your code here, for the general case 
    } 

    //this is an overload, not a specialization of the above function template! 
    void doFun(const resolver<int> &) 
    { 
     //this function will get executed when C = int 
     //so write your code here, for the special case when C = int 
    } 
}; 

注意的重要一點:doFun(const resolve<int>&)是一個重載函數,它不是一個專業化函數模板。您不能專門化成員函數模板沒有專門化封閉的類模板。

閱讀這些文章:

+0

感謝您的回答。我想我明白髮生了什麼,我即將嘗試。 – Michael 2011-06-05 00:43:53

0

在解析式調度爲@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); 
    } 
}; 

雖然這導致了很多的類包裝和專業版本的...

另一個想法,這可以說是相當瘋狂的,是沒有功能的班級,但功能。那些得到專業化,然後叫。這是更詳細的,但允許更好地訪問你想要專門化的功能。雖然,如果他們想訪問私人部分,現在需要讓所有人都成爲朋友。 :/

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; 
}; 
+0

如果'myClassFuncs :: MyFunc'訪問'myClass'的私有成員,那麼你必須使它成爲'friend'。 – Nawaz 2011-06-03 15:40:27

+0

@Nawaz -Static成員函數可以訪問類聲明的私有部分。 – Mahesh 2011-06-03 15:46:56

+0

@Mahesh:一個類的靜態成員函數可以訪問只有**類的私有成員。但是'myClassFuncs'與'myClass'是不同的類。 – Nawaz 2011-06-03 15:49:00