我怎样才能为一系列整数值专门化C ++模板?
有一种方法可以根据一系列值而不是一个模板进行专门化吗? 我知道下面的代码是无效的C ++代码,但它显示了我想要做的。 我正在编写一个8位机器的代码,所以使用整数和字符的速度有所不同。
template<unsigned SIZE> class circular_buffer { unsigned char buffer[SIZE]; unsigned int head; // index unsigned int tail; // index }; template<unsigned SIZE <= 256> class circular_buffer { unsigned char buffer[SIZE]; unsigned char head; // index unsigned char tail; // index };
试试std :: conditional :
#include <type_traits> template<unsigned SIZE> class circular_buffer { typedef typename std::conditional< SIZE < 256, unsigned char, unsigned int >::type index_type; unsigned char buffer[SIZE]; index_type head; index_type tail; };
如果你的编译器还不支持C ++ 11的这一部分,那么在boost库中是相当的。
然后再次,很容易推出自己的(信贷到KerrekSB):
template <bool, typename T, typename F> struct conditional { typedef T type; }; template <typename T, typename F> // partial specialization on first argument struct conditional<false, T, F> { typedef F type; };
使用额外的默认bool
参数:
// primary template handles false template<unsigned SIZE, bool IsSmall = SIZE <= 256> class circular_buffer { unsigned char buffer[SIZE]; unsigned int head; // index unsigned int tail; // index }; // specialization for true template<unsigned SIZE> class circular_buffer<SIZE, true> { unsigned char buffer[SIZE]; unsigned char head; // index unsigned char tail; // index };
另一个可能的select
template <unsigned SIZE> struct offset_size { typedef typename offset_size<SIZE - 1>::type type; }; template <> struct offset_size<0> { typedef unsigned char type; }; template <> struct offset_size<257> { typedef unsigned int type; }; template<unsigned SIZE> class circular_buffer { unsigned char buffer[SIZE]; typename offset_size<SIZE>::type head; // index typename offset_size<SIZE>::type tail; // index };
( Ideone例子 )
我讨厌如何处理types的混乱,所以我提出了一些更简单的方法,利用constexpr
。 当不需要变化的types时,这种变体允许不同的行为,并且满足了在一个范围内而不仅仅是一个值的需要:
template<bool> struct If; constexpr bool InClosedRange(std::size_t Value, std::size_t Lower, std::size_t Upper) { return (Lower <= Value) && (Value <= Upper); } // Usage: template<size_t Width, If<true>> class Foo; template<size_t Width, If<InClosedRange(Width, 1, 41)>> class Foo { /* ... */ }; template<size_t Width, If<InClosedRange(Width, 42, 142)>> class Foo { /* ... */ };
启发: https : //stackoverflow.com/a/9516959/929315