2010-11-11 78 views
4

我有一個有很多功能,但本質上是一個向量類模板類。我想添加一個函數只是布爾類型。專業模板類成員函數只有一種類型的

#include <vector> 
template <typename T> 
class reflected{ 
    private: 
     T*dev_; 
     T*host_; 
     ar_size size; 
     reflected<T>& operator=(reflected<T>& rhs);//do not impliment. assign not allowed. 
     reflected(reflected<T>& old); //do not impliment. Copy not allowed. 
    public: 
     reflected():size(0L),dev_(NULL),host_(NULL){} 
     reflected(ar_size n):size(n),dev_(NULL),host_(NULL){init();} 
     reflected(const T*x,ar_size n):size(n),dev_(NULL),host_(NULL){init();set(x);} 
     ~reflected(); 
     void init(); 
     void init(ar_size n); 
     void init(const T*x,ar_size n); 
     void set(const T * x); 
     void setat(ar_index i, T x); 
     const T getat(ar_size i); 
     const T * devPtr(); 
     const T operator [](const ar_index i); 
     ar_size length(){return size;} 
}; 

我想一個函數vector<ar_index> reflected<bool>::which()增加反射類,這是它將使意義的唯一個案的特殊情況。做這個的最好方式是什麼。編譯器似乎不喜歡添加which()來反射,只爲bool定義它。

回答

12

,如果你對他們T你沒有給予適當的定義中reflected<T>which您可以在類模板定義它像這樣

template <typename T> struct id { typedef T type; }; 

template <typename T> 
class reflected{ 
    private: 
     /* ... */ 
     vector<ar_index> which(id<bool>) { 
      /* ... */ 
     } 
    public: 
     /* ... */ 
     vector<ar_index> which() { return which(id<T>()); } 
}; 

這給出了一個編譯時錯誤。

+0

我不確定他/她是否希望該方法失敗或者只是它沒有被定義*,而是用於*'bool'。無論如何,你的解決方案是非常好的:) – 2010-11-11 21:39:52

+0

這與John Dibling的答案相比如何?額外的「間接」是否有任何優勢?謝謝 – icecrime 2010-11-11 21:50:42

+0

@icecrime你不需要重複構造函數,它可以縮放。如果某個函數只對'int'有意義而對其他函數沒有意義,則不需要另一個派生類。我喜歡爲此使用重載。 – 2010-11-11 22:04:21

4

如果你想添加只有一個問題,你可以與專業化相結合的產業,

template <typename T> 
class reflected_base { 
    // your current 'reflected' contents go here 
}; 

template <typename T> 
class reflected : public reflected_base { }; 

template <> 
class reflected<bool> : public reflected_base { 
    vector<ar_index> which(); 
}; 

這種方法的缺點是,你必須重新實現某些操作(析構函數,拷貝構造函數等)每個專業。另一種選擇是:

template <typename T> 
class specialized_reflected { }; 

template <> 
class specialized_reflected<bool> { 
public: 
    vector<ar_index> which(); 
}; 

template <typename T> 
class reflected : public specialized_reflected<T> { 
    // your current 'reflected' contents go here 
}; 

儘管如此,依賴名稱查找仍然存在潛在的問題。第三個選項(可能是我選擇的一個)將使用非成員函數:

vector<ar_index> which(reflected<bool>&); 
+0

'+ 1'由90secs打我! – sbi 2010-11-11 21:31:56

+0

你需要''爲reflected_base也在聲明中反映出來。但是,那麼爲什麼你確實需要reflect_base? – 2010-11-11 21:33:46

+0

@Diego:所以主'反射'模板和'反射'的每個特化都可以使用相同的成員。 – 2010-11-11 21:34:53

1

不能按照你想要的方式直接完成。但是您可以通過不爲任何類定義reflected()來獲得類似的結果,除了專門的類。那麼如果你嘗試在一個不支持的類上使用它,你會得到一個班輪錯誤。

#include <string> 
#include <sstream> 
using namespace std; 

template<typename A> 
class Gizmo 
{ 
public: 
    Gizmo(){}; 
    int which();  
}; 

template<> int Gizmo<bool>::which() 
{ 
    return 42; 
} 

int main() 
{ 

    Gizmo<bool> gb; 
    gb.which(); 

    Gizmo<int> gi; 
    gi.which(); // LINKER ERROR for Gizmo<int>which() 

    return 0; 
} 
+0

snap!但我會將其描述爲「添加which()來反映並僅爲bool定義它。」這是OP說他在做什麼。 – 2010-11-11 21:38:56

+0

我解釋了OP的描述,好像她正試圖重新定義這個類的'bool'專業化。 – 2010-11-11 21:41:51

+0

重新閱讀後,您可能是對的。如果OP迴應這是他正在做的,我會刪除它。 – 2010-11-11 21:43:13

0

您可以將vector<ar_index> reflected<bool>::which()添加到reflected<bool>(並且僅限於它,而不是普通模板)。如果你得到一個錯誤,也許你沒有做正確的模板特...