我在其他主题中找到了这段代码
template<size_t N, size_t I = 0>
struct hash_calc
{
static constexpr size_t apply(const char(&s)[N])
{
return (hash_calc < N, I + 1 >::apply(s) ^ s[I]) * 16777619u;
};
};
template<size_t N>
struct hash_calc<N, N>
{
static constexpr size_t apply(const char(&s)[N])
{
return 2166136261u;
};
};
template<size_t N>
constexpr size_t hash(const char(&s)[N])
{
return hash_calc<N>::apply(s);
}
首先,我完全不知道为什么它不会成为无限递归调用?根据我的理解,首先hash_calc<N, I>
始终会调用自身,是什么导致hash_calc<N, N>
在I
到达N
时导致其中断? hash_calc<N, I>
时N == I
的模板实例化不会失败。
第二 - 我试图复制粘贴hash_calc<N, N>
结构hash_calc<N, I>
,导致编译错误error: 'hash_calc' is not a class template struct hash_calc<N, N>
。那是为什么?!
编辑: 下面修改的代码不能在msvc和gcc下编译。我刚把一个模板放在其他模板上。发生了什么事?
template<size_t N>
struct hash_calc<N, N>
{
static constexpr size_t apply(const char(&s)[N])
{
return 2166136261u;
};
};
template<size_t N, size_t I = 0>
struct hash_calc
{
static constexpr size_t apply(const char(&s)[N])
{
return (hash_calc < N, I + 1 >::apply(s) ^ s[I]) * 16777619u;
};
};
template<size_t N>
constexpr size_t hashq(const char(&s)[N])
{
return hash_calc<N>::apply(s);
}
答案 0 :(得分:0)
我完全不知道为什么它不会成为无限递归调用?
让我们一步一步地看一下。
hashq<N>(const char(&s)[N])
来电hash_calc<N>::apply(s);
。
那是:
template<size_t N, size_t I = 0>
struct hash_calc
{
static constexpr size_t apply(const char(&s)[N])
{
return (hash_calc < N, I + 1 >::apply(s) ^ s[I]) * 16777619u;
};
};
I==0
。
现在调用hash_calc < N, I + 1 >::apply(s)
I==1
,I==N
,直到template<size_t N>
struct hash_calc<N, N>
{
static constexpr size_t apply(const char(&s)[N])
{
return 2166136261u;
};
};
。那是什么时候
template<size_t N, size_t I = 0>
struct hash_calc
{
static constexpr size_t apply(const char(&s)[N])
{
return (hash_calc < N, I + 1 >::apply(s) ^ s[I]) * 16777619u;
};
};
被调用。递归就结束了。
为什么?!
<N,I>
是更一般的情况,它处理任何一对template<size_t N>
struct hash_calc<N, N>
{
static constexpr size_t apply(const char(&s)[N])
{
return 2166136261u;
};
};
,而
<N,N>
是它的专业化,它只能处理this
的情况。
编译器首先需要一般情况,然后是特殊情况。