I wish to write a template structure foo
such that foo<N>::value_type
is the nearest sized integer (rounding up) to N
. For example foo<32>::value_type => uint32_t
, foo<33>::value_type => uint64_t
and foo<72>::value_type => uint64_t
.
To do this I need an elegant means of providing partial specializations of foo
for a range of values, e.g, 1 <= N <= 8
to return uint8_t and so on and so fourth. Is there a开发者_开发技巧 means of accomplishing this without having to specialise everything from 0 to 64.
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;
};
In c++11 you can use 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;
You can decide which one is less readable.
@hansmaad answer is a nice answer, but I would prefer to use (guess what?!) Boost:
boost::uint_t<N>::least // N: bits
The smallest, built-in, unsigned integral type with at least N bits. The parameter should be a positive number. A compile-time error results if the parameter is larger than the number of bits in the largest integer type.
Template parameters need to be concrete, so I don't think there's any way to avoid specializing for each required value.
精彩评论