Clang. Fatal error: recursive template instantiation exceeded maximum depth

Clang. Fatal error: recursive template instantiation exceeded maximum depth

我有一个 class Index 类似于 std::integer_sequence:

template<std::size_t... NValues>
struct Index { };

我想用序列 N-1, N-2, ..., 2, 1, 0 填充它。

template<std::size_t N>
struct MakeIndex
{
private:
    template<std::size_t I, std::size_t... NIndexValues>
    struct _Make;

public:
    using Type = typename _Make<N>::Type;

private:
    template<std::size_t I, std::size_t... NIndexValues>
    struct _Make
    {
        using Type = typename _Make<I - 1, NIndexValues..., I - 1>::Type;
    };
    template<std::size_t... NIndexValues>
    struct _Make<0, NIndexValues...>
    {
        using Type = Index<NIndexValues...>;
    };
};

int main()
{
    using T = MakeIndex<5>::Type;
}

在 clang 编译器 (3.7.0) 上,它产生

fatal error: recursive template instantiation exceeded maximum depth of 256

Example

它在 VS 和 GCC 上运行良好。也许我做错了什么?或者它是编译器错误?

在我看来像是 clang 编译器错误。如果你不使用前向声明,它也会在 clang 上编译:

template<std::size_t N>
struct MakeIndex
{
private:
    template<std::size_t I, std::size_t... NIndexValues>
    struct _Make
    {
        using Type = typename _Make<I - 1, NIndexValues..., I-1>::Type;
    };
    template<std::size_t... NIndexValues>
    struct _Make<0, NIndexValues...>
    {
        using Type = Index<NIndexValues...>;
    };
public:
    using Type = typename _Make<N>::Type;
};

live example

它看起来像是一个编译器错误,但我不确定问题是出在 clang 上还是出在 gcc 和 msvc 上。

看起来 clang 在使用 0 调用时不会使用模板特化。(您可以添加静态断言以使错误更具可读性)。

您遇到的问题与您定义的using有关。目前编译器正在解析这个使用,它只知道 _Make 的一个定义,它不是专门的,并且以某种方式实例化模板,它只使用这个信息。 如果我们早点添加专业化,它会编译。

live example

由于 GCC 在没有前向声明的情况下无法编译,因此声明是查找的必要条件,因此我猜测 GCC 正在解析 class,但实际上当时并未声明,它很可能不应该这样做。

但是,为了确保正确的行为,我建议只记录 a bug. If it ain't a bug in the compiler it is logged on, they will most likely explain why the other is wrong, which you can use to log the second bug