2011-10-04 51 views
7

我希望編寫一個模板結構foo,這樣foo<N>::value_type是最接近大小的整數(舍入)爲N。例如foo<32>::value_type => uint32_tfoo<33>::value_type => uint64_tfoo<72>::value_type => uint64_t一系列值的模板特化

要做到這一點,我需要一個優雅的方法來爲一系列值提供foo的部分特化,例如1 <= N <= 8返回uint8_t等等等等。有沒有實現這一點,而不必專門一切從0到64

+0

不會有直接的方式(像馬克說),但也許一些聰明的模板元編程技巧。很好的問題,等待看到答案。 –

回答

14
template<size_t N> struct select { typedef uint64_t result; }; 
template<> struct select<0> { typedef uint8_t result; }; 
template<> struct select<1> { typedef uint16_t result; }; 
template<> struct select<2> { typedef uint32_t result; }; 

template<size_t N> 
struct foo 
{ 
    enum{D = (N > 32 ? 3 : (N > 16 ? 2 : (N > 8 ? 1 : 0)))}; 

    typedef typename select<D>::result value_type; 

    value_type value; 
}; 

你可以使用std::conditional

typedef 
    typename std::conditional<(N > 32), uint64_t, 
    typename std::conditional<(N > 16), uint32_t, 
    typename std::conditional<(N > 8), uint16_t, uint8_t> 
    ::type>::type>::type value_type; 

你可以決定哪一個是的可讀性。

+1

我喜歡被證明是錯誤的。 –

+2

很好的答案。不應該枚舉enum {D =(N> 32?3:(N> 16?2:(N> 8?1:0)))};'?下面是它的工作:http://ideone.com/OgXaz – filipe

+0

哇哦,我已經在過去做到了這一點,但是這是_much_比我的版本簡單!雖然礦山有布爾(1),字符(2-8),...,很長很長(33-64),和無效(65歲以上) –

1

模板參數的手段必須是具體的,所以我不認爲有任何方式,以避免專門爲每個需要的值。

7

@hansmaad答案是一個很好的答案,但我更喜歡使用(你猜怎麼着?!)Boost

boost::uint_t<N>::least // N: bits 

最小的,內置的,無符號整數類型至少有N位。 參數應該是一個正數。編譯時錯誤 的結果,如果參數大於比特在 最大整數類型的數量。

+0

很可愛的,更是這樣,因爲我使用升壓在我的項目,但它不處理富<72> :: VALUE_TYPE的解決放至最大整數的情況。 –