2011-10-04 7 views
7

テンプレート構造foofoo<N>::value_typeが最も近いサイズの整数(N)に書きたいと考えています。例えば、foo<32>::value_type => uint32_t,foo<33>::value_type => uint64_tおよびfoo<72>::value_type => uint64_t値の範囲に対するテンプレートの特殊化

これを行うには、1 <= N <= 8からuint8_tを返すなど、ある程度の範囲で部分的な特殊化をfooに提供するという洗練された手段が必要です。 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を決めることができます。

+1

私は間違った証明が大好きです。 –

+2

すばらしい答え。 enum {D =(N> 32?3:(N> 16?2:(N> 8?1:0)))};ここにそれは働いている:http://ideone.com/OgXaz – filipe

+0

ああ、私は過去にこれをやったが、これは私のバージョンよりもずっと簡単です!私のものはbool(1)、char(2-8)、...、long long(33-64)、void(65+) –

1

テンプレートパラメータは具体的にする必要があるので、それぞれの必要な値に特化しないようにする方法はないと思います。

7

@hansmaadの答えは素晴らしい答えですが、私は(?!何を推測)を使用することを好むだろうBoost

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

少なくともNビットの最小、ビルトイン、符号なし整数型。 パラメータは正の数値でなければなりません。パラメータが 最大整数型のビット数より大きい場合、コンパイル時エラー が発生します。

+0

非常にかわいいです、私のプロジェクトではboostを使用していますが、foo <72> :: value_typeのケースを扱うことはできません。 –

関連する問題