混亂,我發現這段代碼在其他話題編譯時間哈希 - 模板演繹順序
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>
總是打電話給自己,當I
達到N
時,是什麼導致它在hash_calc<N, N>
處中斷?當N == I
時,hash_calc<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);
}
模板實例化過程將盡可能在主模板上使用部分特化。畢竟,這就是提供專業化的重點 - 這樣,當它們與實際參數相匹配時,它們就可以得到使用。您似乎認爲主模板必須在專業化被考慮之前未能實例化 - 事實並非如此。 –
*「我試着將'hash_calc'struct複製粘貼到'hash_calc ''*我不明白你的意思。如果你有一段產生編譯器錯誤的代碼,那麼顯示那段代碼和編譯器錯誤的確切文本。 –
我修改了第一篇文章 – QQemka