constexpr模板函数的无限递归

时间:2019-05-10 23:56:47

标签: c++ templates generics const constexpr

我用constexpr函数在C ++中实现了FNV-1A函数,但遇到一个奇怪的问题。

此版本可以正常工作:

template<size_t N>
static constexpr uint32_t fnv1a_internal(const char (&data)[N], size_t position, uint32_t state) {
    return position >= N - 1 ? state : fnv1a_internal(data, position + 1, (state ^ data[position]) * 16777619UL);
}

template<size_t N>
static constexpr uint32_t fnv1a(const char (&data)[N]) {
    return fnv1a_internal(data, 0, 2166136261UL);
}

但是当我将const泛型参数设为位置时,

template<size_t N, size_t Position>
static constexpr uint32_t fnv1a_internal(const char (&data)[N], uint32_t state) {
    return Position >= N - 1 ? state : fnv1a_internal<N, Position + 1>(data, (state ^ data[Position]) * 16777619UL);
}

template<size_t N>
static constexpr uint32_t fnv1a(const char (&data)[N]) {
    return fnv1a_internal<N, 0>(data, 2166136261UL);
}

实例化后,编译器会抱怨该函数超出了递归限制,因此无法编译。

该函数旨在与像这样的字符串文字一起使用:

uint32_t hash = fnv1a("Hello world");

问题出在哪里?

1 个答案:

答案 0 :(得分:3)

三元操作不能避免模板实例化。

因此,当Position >= N - 1时,您仍将实例化fnv1a_internal<N, Position + 1>并将其实例化fnv1a_internal<N, Position + 2>,依此类推。