我不确定在这种情况下是否有任何意义上的比特是非类型模板:
template< int bits >
inline bool FitsInBits(int x )
{
#if bits >= 32
#error 'bits' should be less than 32
#endif
return x >= -((int)1<<(bits-1)) && x < ((int)1<<(bits-1));
}
而不是:
inline bool FitsInBits(int x, int bits )
{
return x >= -((int)1<<(bits-1)) && x < ((int)1<<(bits-1));
}
据我所知,编译器会在第一种情况下在编译时创建许多FitsInBits变体?但我不明白这将如何优化计算。
答案 0 :(得分:1)
模板不一定更多效率,但它可以确保:-((int)1<<(bits-1))
和((int)1<<(bits-1))
的值可以在编译时计算,所以所有在运行时发生的基本上是:
return x >= constant_a && x < constant_b;
反过来,这非常简单,编译器很可能会/将为它生成内联代码。
假设bits
是编译时已知的值,非模板版本可以(也可能会)执行相同的操作 - 但由于bits
是普通函数的正常参数,你可能(可能是偶然)传递了bits
的一些值,直到运行时才知道它(例如,根据用户输入的数据)。
如果你这样做,编译器就不会给你一个关于这样做的警告 - 在这种情况下,表达式可能赢了如上所述减少为常数,因此您很可能最终得到的代码将1
加载到一个寄存器中,将bits
加载到另一个寄存器中,递减第二个,将第一个左移一个数字在第二个中指定的地方,与x
比较,有条件地跳转到标签,否定第一个,再次比较,做另一个条件跳转等等。这仍然只有十几个指令(或者说),但毫无疑问比值是常数时慢。