2013-02-20 141 views
0

我想做一些看起來很簡單使用模板,但我不能讓它工作。該類正在爲AVR處理器實現各種串行IO實現,但問題是一個通用的C++問題。目標是在編譯時根據模板參數製作選項,以便用戶友好並增加代碼重用,並在某些地方由於重用而提高性能。C++模板部分類專業化與功能專業

問題很簡單,但我找不到解決方案(如果有的話)。當編譯下面使用Visual Studio 2008的代碼我得到:

error C2039: 't1' : is not a member of 'Interface<T1,0,_C> 
error C2039: 't1' : is not a member of 'Interface<T1,1,_C> 
error C2039: 't2' : is not a member of 'Interface<T2,0,_C> 
error C2039: 't2' : is not a member of 'Interface<T2,1,_C> 

**我已經拆了我的測試代碼到解釋塊,把它們放在一起進行整體測試情況**

這是的「通用」基本模板:

enum eType { T1, T2 }; 
enum eT1 { T1_I1, T1_I2 }; 
enum eT2 { T2_I1, T2_I2 }; 

//This defines the 'global/default' interface that is required 
template< eType _T, int _I, typename _C> 
struct Interface 
{ 
    bool initialise(); 
}; 

爲此,我部分專門基於所述_T參數模板中添加由INITIALISE使用成員變量()等等:

//t1 has a new member function which initialise() uses 
template< int _I, typename _C> 
struct Interface< T1, _I, _C > 
{ 
    bool initialise(); 
    void t1(); 
}; 

//t2 has a new member function which initialise() might uses 
template< int _I, typename _C> 
struct Interface< T2, _I, _C > 
{ 
    bool initialise(); 
    void t2(); 
}; 

//We can implement a function for T1 type 
template< int _I, typename _C> 
bool Interface< T1, _I, _C >::initialise() 
{ printf("T1 initialise\n"); return true; } 

//We can implement a function for T2 type 
template< int _I, typename _C> 
bool Interface< T2, _I, _C >::initialise() 
{ printf("T2 initialise\n"); return true; } 

//We can implement a function for T1 special function 
template< int _I, typename _C> 
void Interface< T1, _I, _C >::t1() 
{ printf("T1\n"); } 

//We can implement a function for T2 special function 
template< int _I, typename _C> 
void Interface< T2, _I, _C >::t2() 
{ printf("T2\n"); } 

現在到了我無法弄清楚如何根據第二個模板參數_I來專門實現t1()和t2()函數的地方。

//################ ISUE BELOW ################### 

//ERROR: We can't implement the special function for T1 based on _I specialization 
template< typename _C> 
void Interface< T1, (int)T1_I1, _C >::t1() 
{ printf("T1_I1 Special function\n"); } 

//ERROR: We can't implement the special function for T1 based on _I specialization 
template< typename _C> 
void Interface< T1, (int)T1_I2, _C >::t1() 
{ printf("T1_I2 Special function\n"); } 

//ERROR: We can't implement the special function for T2 based on _I specialization 
template< typename _C> 
void Interface< T2, (int)T2_I1, _C >::t2() 
{ printf("T2_I1 Special function\n"); } 

//ERROR: We can't implement the special function for T2 based on _I specialization 
template< typename _C> 
void Interface< T2, (int)T2_I2, _C >::t2() 
{ printf("T2_I2 Special function\n"); } 

//################ ISUE END ################### 

我們在main()函數測試中,它的所有編譯:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    struct Config {}; 
    Interface<T1, T1_I1, Config> t1i1; 
    Interface<T1, T1_I2, Config> t1i2; 
    Interface<T2, T2_I1, Config> t2i1; 
    Interface<T2, T2_I2, Config> t2i2; 

    t1i1.initialise(); 
    t1i2.initialise(); 
    t1i1.t1(); 
    t1i2.t1(); 

    t2i1.initialise(); 
    t2i2.initialise(); 
    t2i1.t2(); 
    t2i2.t2(); 
    return 0; 
} 

的問題會被編譯器造成沒有看到原始類專業化的存在和它使用的是非專用接口,它沒有t1()或t2()。我在哪裏得到的語法錯誤,或者是否有簡單的黑客/解決方法來完成我正在嘗試做的事情。只要解決方案能夠以Serial<UART,Hardware,Config> io的形式產生一個類型,它就符合我的目標!

+0

你不能做到這一點。函數模板不能被部分地專門化。 – 2013-02-20 23:41:30

回答

0

你必須一一列出所有部分專業化。例如:

template <eType E, int I, typename T> struct Interface; 

template <int I, typename T> struct Interface<T1, I, T> 
{ 
    void t1() { /* ... */ } 
    bool initialize() { /* ... */ } 
}; 

template <typename T> struct Interface<T1, static_cast<int>(T1), T> 
{ 
    void t1() { /* ... */ } 
    bool initialize() { /* ... */ } 
}; 

您可以隨時考慮您的代碼,以避免在適當時重複。例如:

namespace detail 
{ 
    template <typename T, int I> struct T1Helper 
    { 
     static bool initialize() { /* ... */ } 
    }; 
} 

// ... primary template as above ... 

template <int I, typename T> struct Interface<T1, I, T> 
{ 
    void t1() { /* ... */ } 
    bool initialize() { return detail::T1Helper<T, I>::initialize(); } 
}; 

// etc. 

或者你也可以因素的共同代碼放到一個混合模板:

template <int I, typename T> 
struct Interface<T1, I, T> : Mixin<T, I> 
{ 
    void t1() { /* ... */ } 
}; 
+0

感謝您的回覆。我發現無法獲得部分功能專業化,並且您的三個示例在展示如何解決此問題方面非常有用。我將嘗試一個MixIn的版本,它是一個Helper,它將會擁有我需要的所有功能。再次感謝你的幫助。 – Crog 2013-02-21 09:58:28