2010-08-12 139 views
3

我有一個模板類,如下所示:部分專業模板成員函數

template <template <class TypeT> class PoolT=pool_base> 
struct pool_map 
{ 
public: 
    template <typename U> struct pool { typedef PoolT<U> type }; 

public: 
    template <typename T, size_t S=sizeof(T)> 
    T& get(size_t index); 

private: 
    pool<uint8_t>::type pool8_; 
    pool<uint16_t>::type pool16_; 
    pool<uint32_t>::type pool32_; 
    pool<uint64_t>::type pool64_; 
}; 

template <template <class TypeT> class PoolT> 
template <typename T, size_t S> 
inline 
T& pool_map<PoolT>::get(size_t index) 
{ 
    // Default case 
} 

template <template <class TypeT> class PoolT> 
template <typename T> 
inline 
T& pool_map<PoolT>::get<T,8>(size_t index) 
{ 
    // Dispatch to pool8_ 
} 

template <template <class TypeT> class PoolT> 
template <typename T> 
inline 
T& pool_map<PoolT>::get<T,16>(size_t index) 
{ 
    // Dispatch to pool16_ 
} 

template <template <class TypeT> class PoolT> 
template <typename T> 
inline 
T& pool_map<PoolT>::get<T,32>(size_t index) 
{ 
    // Dispatch to pool32_ 
} 

你顯然注意到了,我寫的東西有可能在一個美妙的和理想的世界裏,默認模板參數和部分特化模板方法是可能的(不需要專門研究整個類)。

我想聽聽有關建議,以達到相同的效果,也就是說,能夠爲每個大小S有一個專門的方法,以便我可以選擇適當的池使用。我試圖在pool_map中添加一個get_pool<size_t>,但幾乎發生同樣的問題:我不能專門化內部類,而沒有專門化外部類...

我想到的唯一解決方案是使用外部的get_pool<size_t>類會將pool_map作爲參數並返回對poolX_成員的引用,但我想避免它,因爲它似乎不是「真正的靜態方法」。

感謝您的閱讀!

回答

3

有一個簡單的解決方案(也許你沒有想到吧),它是:

template <typename T> 
T& pool_map<PoolT>::get(size_t index) 
{ 
    if (sizeof(T) * CHAR_BIT == 8) { 
    // Dispatch to pool8_ 
    } else if (sizeof(T) * CHAR_BIT == 16) { 
    // Dispatch to pool16_ 
    } else if (...) { 
    ... 
    } else { 
    // Default case 
    } 
} 

但是,因爲這將可能給你的編譯錯誤(取決於你放什麼,而不是「派遣...「)你可以簡單地重載get()函數。

template <typename T> 
typename std::enable_if<sizeof(T) * CHAR_BIT == 8,T>::type& 
    get(size_t index) 
{ 
    ... 
} 

template <typename T> 
typename std::enable_if<sizeof(T) * CHAR_BIT == 16,T>::type& 
    get(size_t index) 
{ 
    ... 
} 

etc. 

唯一的問題是,默認的實現(如果需要的話)需要像sizeof(T) * CHAR_BIT != 8 && sizeof(T) * CHAR_BIT != 16 && sizeof(T) * CHAR_BIT != 32 && sizeof(T) * CHAR_BIT != 64

最後的解決方案(最好的一個我想說的)的條件仍然使用私有類一個靜態函數,你可以專門化(你所說的不是「真正的靜態方式」)

+0

我設法解決這個問題。感謝您的非常準確和詳盡的答案:) – NewbiZ 2010-08-13 13:03:19

0

一個解決方案是使用enable_ifdisable_if(通常),雖然我沒有測試過它。

另一種解決方案是簡單地轉發實現細節給助手:

namespace helper 
{ 
    template <class T> struct getter { static void Do() {} }; 

    // specializations by type 
} 

template <class T> 
T& pool_map<T>::get(size_t index) { return helper::getter<T>::Do(); }