如何为一系列整数值专门化C++模板?

Mik*_*ike 41 c++ templates

有没有办法根据一系列值而不是一个值进行模板专业化?我知道以下代码不是有效的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
};
Run Code Online (Sandbox Code Playgroud)

jro*_*rok 47

尝试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;
};
Run Code Online (Sandbox Code Playgroud)

如果你的编译器还不支持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;
}; 
Run Code Online (Sandbox Code Playgroud)

  • 像`std :: conditional`这样的特性对于自己来说是微不足道的,所以如果你没有它,你真的不需要任何库:`template <bool,typename T,typename> struct conditional {typedef T type; }; template <typename T,typename U> struct conditional <false,T,U> {typedef U type; };` (7认同)

R. *_*des 33

使用额外的默认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
};
Run Code Online (Sandbox Code Playgroud)

  • @MooingDuck没必要.`<`小于默认值.这就是为什么存在`template` disambiguator.令人困惑的是`>`是默认情况下关闭的模板,你需要parens.C++很棒,不是吗? (3认同)
  • @ R.MartinhoFernandes:如果是_needed_我会编辑这个问题.我只是说我会__happier_.你仍然得到+1. (2认同)

cdh*_*wie 7

另一种可能选择:

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
};
Run Code Online (Sandbox Code Playgroud)

(Ideone示例)

  • 你是一个虐待狂,编译器是如此残酷.尝试编译`offset_size <MAX_INT>`,编译器必须实例化数十亿个模板类! (8认同)