2012-09-17 37 views
2

我有一個模板類,唯一的模板參數是typename。專門爲幾個可能的參數類型(typenames)

template<typename T> 
class Reader{ 
    ... 
} 

現在我想專門爲它的每個整數類型,是這樣的:

template<typename T - integral> 
class Reader{ 
    //another code 
} 

我怎樣才能做到這一點?

+0

您可以將無聲(默認)模板參數添加到'Reader'嗎? – Grizzly

+0

@Grizzly:不,這對我來說不是好主意 – RiaD

+0

在這種情況下,我認爲如果沒有明確地專業化每種類型,你就會走運 – Grizzly

回答

2

您可以使用虛擬std::true_type參數

template<typename T, typename = std::true_type> 
class Reader { 

}; 

template<typename T> 
class Reader<T, std::integral_constant<bool, 
        std::is_integral<T>::value> > { 
    // ... 
}; 

順便說一句,你會看到void,而不是true_type使用這種模式,與專業化往往採用enable_if和更復雜(SFINAE涉及)的條件。

+0

你可以舉個例子'enable_if'嗎?你的例子工作正常,我嘗試了一些'enable_if',但我得到編譯錯誤#include template class Name; 模板 類名稱 ::值,int>的::類型> { }; int main(){ 名稱名稱; } – RiaD

+0

另一種方法是使用'typename std :: is_integral :: type'作爲匹配的第二個參數。 –

+1

@RiaD你需要在'std :: enable_if'之前加上'typename'。 –

5

您只需一個額外的違約布爾參數:

template<typename T, bool IsIntegral = std::is_integral<T>::value> 
class Reader{ // primary template, used for non-integrals 
    ... 
} 

template<typename T> 
class Reader<T, true> { // specialization for integral types 
    ... 
} 
+0

是的,我忘了補充一點,我知道這個解決方案。但我希望能夠添加新的專業組(即浮動,字符串(wstring,字符串,字符*)等),而無需修改舊代碼。 – RiaD

+2

你的意思是你不能改變'Reader'主模板?如果是這樣,你的運氣不好。 –

+0

展示通常的解決方案(主要模板匹配任何東西,跨特性分割的專業化)可能仍然很有趣。 –

3

在類似的情況下,我已經使用專業類模板的所有特殊類型的強制方法。我意識到這些是相當多的,它會變得很快而且很痛苦。然而,把有趣的成員分解成所有專業共享的基類是合理的。在我使用這種方法的情況下,我通常只在類中有靜態成員,即構造函數沒有被繼承的事實不是問題(C++ 2011支持繼承構造函數的語法,但同時要保持符號下降):

template <typename T> class Reader { ... }; 

template <typename T> class IntReader { /* special version for integers */ }; 
// to bool or not bool? 
template <> class Reader<wchar_t>: public IntReader<wchar_t> {}; 
template <> class Reader<char>: public IntReader<char> {}; 
template <> class Reader<char16_t>: public IntReader<char16_t> {}; 
template <> class Reader<char32_t>: public IntReader<char32_t> {}; 
template <> class Reader<signed char>: public IntReader<signed char> {}; 
template <> class Reader<signed short>: public IntReader<signed short> {}; 
template <> class Reader<signed int>: public IntReader<signed int> {}; 
template <> class Reader<signed long>: public IntReader<signed long> {}; 
template <> class Reader<signed long long>: public IntReader<signed long long> {}; 
template <> class Reader<unsigned char>: public IntReader<unsigned char> {}; 
template <> class Reader<unsigned short>: public IntReader<unsigned short> {}; 
template <> class Reader<unsigned int>: public IntReader<unsigned int> {}; 
template <> class Reader<unsigned long>: public IntReader<unsigned long> {}; 
template <> class Reader<unsigned long long>: public IntReader<unsigned long long> {}; 

無可否認,我們有太多的整數類型!有不同的字符類型是有點荒謬。

+0

將const和volatile添加到這將是一場噩夢:) –

+0

不,不是:您可以提供泛型特化並讓它們委託給沒有cv限定符的版本。 –

相關問題