【问题标题】:Clang. Fatal error: recursive template instantiation exceeded maximum depth铛。致命错误:递归模板实例化超出最大深度
【发布时间】:2017-01-03 22:36:09
【问题描述】:

我有一个类似于std::integer_sequence 的课程Index

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)上,它产生

致命错误:递归模板实例化超出最大深度 256 个

Example

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

【问题讨论】:

    标签: c++11 recursion variadic-templates clang++


    【解决方案1】:

    在我看来就像一个 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

    【讨论】:

      【解决方案2】:

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

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

      您面临的问题与您定义的using 有关。在编译器解析这个使用的那一刻,它只知道_Make 的一个定义,它不是专门的,并且以某种方式在实例化模板时,它只使用这个信息。 如果我们更早地添加特化,它确实可以编译。

      live example

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

      但是,为了确保正确的行为,我建议只记录 a bug。如果它不是它所登录的编译器中的错误,他们很可能会解释为什么另一个错误,您可以使用它来记录the second bug

      【讨论】:

        猜你喜欢
        • 2014-05-13
        • 2016-12-10
        • 1970-01-01
        • 2018-01-14
        • 2018-12-03
        • 1970-01-01
        • 2017-07-18
        • 2021-12-11
        • 2019-07-03
        相关资源
        最近更新 更多