我有以下代码:
template <int size>
inline uint hashfn( const char* pStr )
{
uint result = *pStr;
switch ( size )
{
case 10:
result *= 4;
result += *pStr;
case 9:
result *= 4;
result += *pStr;
...
...
case 2:
result *= 4;
result += *pStr;
}
return result;
}
此代码是特定长度 DNA 序列的哈希函数,其中长度是模板参数。它是一个展开的循环,带有一个 switch 语句,可在正确的位置跳转。 然而,大小是一个常量,因为它是一个模板参数。 我可以专门针对某些尺寸值吗? 也许有类似的东西:
template <int 2>
inline uint hashfn( const char* pStr )
{
uint result = *pStr;
result *= 4;
++pStr;
result += *pStr;
return result;
}
最佳答案
我倾向于使用模板递归地执行此操作。
例如:
template<class TOp,int factor>
struct recursive_unroll {
__forceinline static void result( TOp& k ) {
k();
recursive_unroll<TOp,factor-1>::result( k );
}
};
template<class TOp>
struct recursive_unroll<TOp,0> {
__forceinline static void result( TOp& k ) {}
};
struct op {
op( const char* s ) : res( 0 ), pStr( s ) {}
unsigned int res;
const char* pStr;
__forceinline void operator()() {
res *= 4;
res += *pStr;
++pStr;
//std::cout << res << std::endl;
}
};
char str[] = "dasjlfkhaskjfdhkljhsdaru899weiu";
int _tmain(int argc, _TCHAR* argv[])
{
op tmp( str );
recursive_unroll<op,sizeof( str ) >::result( tmp );
std::cout << tmp.res << std::endl;
return 0;
}
这为我生成了最佳代码。如果没有 __forceinline,代码将无法正确内联。
在使用此类优化之前,您应该始终对代码进行测试。然后您应该查看程序集并解读编译器已经为您做了什么。但在这种情况下,这似乎是一种插入(对我来说)。
__forceinline 是 Microsoft Visual Studio 特定的扩展。编译器应该生成最佳代码,但事实并非如此。所以这里我使用了这个扩展。
关于c++ - 使用整数模板参数时可以展开循环吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1099427/