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
它在 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;
};
它看起来像是一个编译器错误,但我不确定问题是出在 clang 上还是出在 gcc 和 msvc 上。
看起来 clang 在使用 0 调用时不会使用模板特化。(您可以添加静态断言以使错误更具可读性)。
您遇到的问题与您定义的using
有关。目前编译器正在解析这个使用,它只知道 _Make
的一个定义,它不是专门的,并且以某种方式实例化模板,它只使用这个信息。
如果我们早点添加专业化,它会编译。
由于 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。
我有一个 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
它在 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;
};
它看起来像是一个编译器错误,但我不确定问题是出在 clang 上还是出在 gcc 和 msvc 上。
看起来 clang 在使用 0 调用时不会使用模板特化。(您可以添加静态断言以使错误更具可读性)。
您遇到的问题与您定义的using
有关。目前编译器正在解析这个使用,它只知道 _Make
的一个定义,它不是专门的,并且以某种方式实例化模板,它只使用这个信息。
如果我们早点添加专业化,它会编译。
由于 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。